More work on sockets attempt to get socket command to standard daemon.sock to a running instance. Also, fixed a long standing misspelling in daemon, was deamon, so if your scripts that self-voice or whatever with fenrir no longer work, this is why, please update scripts to the new, correct, daemon.sock.
This commit is contained in:
@@ -88,12 +88,12 @@ Application-specific menus in `vmenu-profiles/KEY/{app}/`:
|
|||||||
|
|
||||||
## Remote Control
|
## Remote Control
|
||||||
|
|
||||||
Unix socket: `/tmp/fenrirscreenreader-deamon.sock`
|
Unix socket: `/tmp/fenrirscreenreader-daemon.sock`
|
||||||
TCP: localhost:22447
|
TCP: localhost:22447
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
echo "command say Hello" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say Hello" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#rate=0.8" | nc localhost 22447
|
echo "setting set speech#rate=0.8" | nc localhost 22447
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ enable_command_remote=True # allow command execution
|
|||||||
### Remote Drivers
|
### Remote Drivers
|
||||||
|
|
||||||
1. **unixDriver** (recommended): Uses Unix domain sockets
|
1. **unixDriver** (recommended): Uses Unix domain sockets
|
||||||
- Socket location: `/tmp/fenrirscreenreader-deamon.sock` for the standard control socket
|
- Socket location: `/tmp/fenrirscreenreader-daemon.sock` for the standard control socket
|
||||||
- `fenrir -x` instances also create private sockets: `/tmp/fenrirscreenreader-<pid>.sock`
|
- `fenrir -x` instances also create private sockets: `/tmp/fenrirscreenreader-<pid>.sock`
|
||||||
- More secure, local-only access
|
- More secure, local-only access
|
||||||
- Works with `socat`
|
- Works with `socat`
|
||||||
@@ -298,99 +298,102 @@ The `socat` command provides the easiest way to send commands to Fenrir:
|
|||||||
#### Instance Discovery
|
#### Instance Discovery
|
||||||
```bash
|
```bash
|
||||||
# List registered Fenrir instances and their socket paths
|
# List registered Fenrir instances and their socket paths
|
||||||
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
In X terminal mode (`fenrir -x`), multiple Fenrir instances can run at the same
|
In X terminal mode (`fenrir -x`), multiple Fenrir instances can run at the same
|
||||||
time. Each instance has a private socket, and one instance may also own the
|
time. Each instance has a private socket, and one instance may also own the
|
||||||
standard control socket. Use `ls` or `command ls` on the standard socket to find
|
standard control socket. Use `ls` or `command ls` on the standard socket to find
|
||||||
the private socket for a specific instance. Untargeted commands sent through a
|
the private socket for a specific instance. Commands sent to the standard socket
|
||||||
shared or broadcast path are claimed by one instance so duplicate instances do
|
are handled by its owner when possible; otherwise they are forwarded to a
|
||||||
not all perform the same action.
|
registered private socket, preferring the sender's Fenrir ancestor when one can
|
||||||
|
be found. Untargeted commands sent through a shared or broadcast path are
|
||||||
|
claimed by one instance so duplicate instances do not all perform the same
|
||||||
|
action.
|
||||||
|
|
||||||
#### Basic Speech Control
|
#### Basic Speech Control
|
||||||
```bash
|
```bash
|
||||||
# Interrupt current speech
|
# Interrupt current speech
|
||||||
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Speak custom text
|
# Speak custom text
|
||||||
echo "command say Hello, this is a test message" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say Hello, this is a test message" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Temporarily disable speech (until next keystroke)
|
# Temporarily disable speech (until next keystroke)
|
||||||
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Settings Control
|
#### Settings Control
|
||||||
```bash
|
```bash
|
||||||
# Enable highlight tracking mode
|
# Enable highlight tracking mode
|
||||||
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change speech parameters
|
# Change speech parameters
|
||||||
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#pitch=0.6" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#pitch=0.6" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#volume=0.9" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#volume=0.9" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change punctuation level (none/some/most/all)
|
# Change punctuation level (none/some/most/all)
|
||||||
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set general#punctuation_level=none" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set general#punctuation_level=none" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Voice and TTS engine control
|
# Voice and TTS engine control
|
||||||
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#module=espeak-ng" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#module=espeak-ng" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Disable sound temporarily
|
# Disable sound temporarily
|
||||||
echo "setting set sound#enabled=False" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set sound#enabled=False" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set sound#volume=0.5" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set sound#volume=0.5" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Keyboard and input settings
|
# Keyboard and input settings
|
||||||
echo "setting set keyboard#char_echo_mode=1" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set keyboard#char_echo_mode=1" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set keyboard#word_echo=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set keyboard#word_echo=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Screen control (ignore specific TTYs)
|
# Screen control (ignore specific TTYs)
|
||||||
echo "setting set screen#ignore_screen=1,2,3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set screen#ignore_screen=1,2,3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Multiple settings at once
|
# Multiple settings at once
|
||||||
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset all settings to defaults
|
# Reset all settings to defaults
|
||||||
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Save current settings
|
# Save current settings
|
||||||
echo "setting save" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting save" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting saveas /tmp/my-fenrir-settings.conf" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting saveas /tmp/my-fenrir-settings.conf" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Clipboard Operations
|
#### Clipboard Operations
|
||||||
```bash
|
```bash
|
||||||
# Place text into clipboard
|
# Place text into clipboard
|
||||||
echo "command clipboard This text will be copied to clipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command clipboard This text will be copied to clipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Export clipboard to file
|
# Export clipboard to file
|
||||||
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Window Management
|
#### Window Management
|
||||||
```bash
|
```bash
|
||||||
# Define a window area (x1 y1 x2 y2)
|
# Define a window area (x1 y1 x2 y2)
|
||||||
echo "command window 0 0 80 24" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command window 0 0 80 24" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset window to full screen
|
# Reset window to full screen
|
||||||
echo "command resetwindow" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command resetwindow" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### VMenu Control
|
#### VMenu Control
|
||||||
```bash
|
```bash
|
||||||
# Set virtual menu context
|
# Set virtual menu context
|
||||||
echo "command vmenu nano/file" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command vmenu nano/file" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset virtual menu
|
# Reset virtual menu
|
||||||
echo "command resetvmenu" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command resetvmenu" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Application Control
|
#### Application Control
|
||||||
```bash
|
```bash
|
||||||
# Quit Fenrir
|
# Quit Fenrir
|
||||||
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using TCP Driver
|
### Using TCP Driver
|
||||||
@@ -590,7 +593,7 @@ Fenrir provides intelligent progress bar detection and audio feedback for variou
|
|||||||
|
|
||||||
To enable progress monitoring:
|
To enable progress monitoring:
|
||||||
1. Add a key binding in your keyboard layout file
|
1. Add a key binding in your keyboard layout file
|
||||||
2. Or use the remote control system: `echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock`
|
2. Or use the remote control system: `echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock`
|
||||||
|
|
||||||
### Progress Detection Patterns
|
### Progress Detection Patterns
|
||||||
|
|
||||||
@@ -651,7 +654,7 @@ Building...
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Enable progress monitoring
|
# Enable progress monitoring
|
||||||
echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command progress_bar_monitor" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Common scenarios where progress monitoring is useful:
|
# Common scenarios where progress monitoring is useful:
|
||||||
wget https://example.com/large-file.zip # Download progress
|
wget https://example.com/large-file.zip # Download progress
|
||||||
@@ -675,7 +678,7 @@ Progress monitoring can be configured through settings:
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# notify_fenrir.sh - Send notifications to Fenrir
|
# notify_fenrir.sh - Send notifications to Fenrir
|
||||||
|
|
||||||
SOCKET="/tmp/fenrirscreenreader-deamon.sock"
|
SOCKET="/tmp/fenrirscreenreader-daemon.sock"
|
||||||
|
|
||||||
fenrir_say() {
|
fenrir_say() {
|
||||||
echo "command say $1" | socat - UNIX-CLIENT:$SOCKET
|
echo "command say $1" | socat - UNIX-CLIENT:$SOCKET
|
||||||
@@ -698,7 +701,7 @@ import os
|
|||||||
|
|
||||||
def send_fenrir_command(command):
|
def send_fenrir_command(command):
|
||||||
"""Send command to Fenrir via Unix socket"""
|
"""Send command to Fenrir via Unix socket"""
|
||||||
socket_path = "/tmp/fenrirscreenreader-deamon.sock"
|
socket_path = "/tmp/fenrirscreenreader-daemon.sock"
|
||||||
if os.path.exists(socket_path):
|
if os.path.exists(socket_path):
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
@@ -731,7 +734,7 @@ send_fenrir_command("setting set speech#rate=0.9")
|
|||||||
**Commands not working:**
|
**Commands not working:**
|
||||||
- Verify `enable_command_remote=True` in settings
|
- Verify `enable_command_remote=True` in settings
|
||||||
- Check Fenrir debug logs: `/var/log/fenrir.log`
|
- Check Fenrir debug logs: `/var/log/fenrir.log`
|
||||||
- Test with simple command: `echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock`
|
- Test with simple command: `echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock`
|
||||||
|
|
||||||
## Command Line Options
|
## Command Line Options
|
||||||
|
|
||||||
|
|||||||
+16
-13
@@ -321,58 +321,61 @@ enable_command_remote=True
|
|||||||
.B Instance Discovery:
|
.B Instance Discovery:
|
||||||
.EX
|
.EX
|
||||||
# List registered Fenrir instances and their socket paths
|
# List registered Fenrir instances and their socket paths
|
||||||
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
In X terminal mode (fenrir -x), multiple Fenrir instances can run at the
|
In X terminal mode (fenrir -x), multiple Fenrir instances can run at the
|
||||||
same time. Each instance has a private socket at
|
same time. Each instance has a private socket at
|
||||||
/tmp/fenrirscreenreader-<pid>.sock, and one instance may also own the
|
/tmp/fenrirscreenreader-<pid>.sock, and one instance may also own the
|
||||||
standard control socket. Use ls or "command ls" on the standard socket to
|
standard control socket. Use ls or "command ls" on the standard socket to
|
||||||
find the private socket for a specific instance.
|
find the private socket for a specific instance. Commands sent to the standard
|
||||||
|
socket are handled by its owner when possible; otherwise they are forwarded to a
|
||||||
|
registered private socket, preferring the sender's Fenrir ancestor when one can
|
||||||
|
be found.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Basic Speech Control:
|
.B Basic Speech Control:
|
||||||
.EX
|
.EX
|
||||||
# Interrupt current speech
|
# Interrupt current speech
|
||||||
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Speak custom text
|
# Speak custom text
|
||||||
echo "command say Hello, this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say Hello, this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Temporarily disable speech
|
# Temporarily disable speech
|
||||||
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Settings Control:
|
.B Settings Control:
|
||||||
.EX
|
.EX
|
||||||
# Enable highlight tracking
|
# Enable highlight tracking
|
||||||
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change speech rate
|
# Change speech rate
|
||||||
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change punctuation level (none/some/most/all)
|
# Change punctuation level (none/some/most/all)
|
||||||
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Voice and TTS control
|
# Voice and TTS control
|
||||||
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Multiple settings at once
|
# Multiple settings at once
|
||||||
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset all settings
|
# Reset all settings
|
||||||
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Clipboard Operations:
|
.B Clipboard Operations:
|
||||||
.EX
|
.EX
|
||||||
# Add text to clipboard
|
# Add text to clipboard
|
||||||
echo "command clipboard Text to copy" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command clipboard Text to copy" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Export clipboard to file
|
# Export clipboard to file
|
||||||
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
.SS Command Reference
|
.SS Command Reference
|
||||||
|
|||||||
+17
-14
@@ -1278,65 +1278,68 @@ The `+socat+` command provides the easiest way to send commands to Fenrir:
|
|||||||
|
|
||||||
....
|
....
|
||||||
# List registered Fenrir instances and their socket paths
|
# List registered Fenrir instances and their socket paths
|
||||||
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
....
|
....
|
||||||
|
|
||||||
In X terminal mode (`+fenrir -x+`), multiple Fenrir instances can run at the
|
In X terminal mode (`+fenrir -x+`), multiple Fenrir instances can run at the
|
||||||
same time. Each instance has a private socket at
|
same time. Each instance has a private socket at
|
||||||
`+/tmp/fenrirscreenreader-<pid>.sock+`, and one instance may also own the
|
`+/tmp/fenrirscreenreader-<pid>.sock+`, and one instance may also own the
|
||||||
standard control socket. Use `+ls+` or `+command ls+` on the standard socket to
|
standard control socket. Use `+ls+` or `+command ls+` on the standard socket to
|
||||||
find the private socket for a specific instance.
|
find the private socket for a specific instance. Commands sent to the standard
|
||||||
|
socket are handled by its owner when possible; otherwise they are forwarded to a
|
||||||
|
registered private socket, preferring the sender's Fenrir ancestor when one can
|
||||||
|
be found.
|
||||||
|
|
||||||
===== Basic Speech Control
|
===== Basic Speech Control
|
||||||
|
|
||||||
....
|
....
|
||||||
# Interrupt current speech
|
# Interrupt current speech
|
||||||
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Speak custom text
|
# Speak custom text
|
||||||
echo "command say Hello, this is a test message" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say Hello, this is a test message" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Temporarily disable speech (until next keystroke)
|
# Temporarily disable speech (until next keystroke)
|
||||||
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
....
|
....
|
||||||
|
|
||||||
===== Settings Control
|
===== Settings Control
|
||||||
|
|
||||||
....
|
....
|
||||||
# Enable highlight tracking mode
|
# Enable highlight tracking mode
|
||||||
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change speech rate
|
# Change speech rate
|
||||||
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change punctuation level (none/some/most/all)
|
# Change punctuation level (none/some/most/all)
|
||||||
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Voice and TTS control
|
# Voice and TTS control
|
||||||
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Multiple settings at once
|
# Multiple settings at once
|
||||||
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset all settings to defaults
|
# Reset all settings to defaults
|
||||||
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
....
|
....
|
||||||
|
|
||||||
===== Clipboard Operations
|
===== Clipboard Operations
|
||||||
|
|
||||||
....
|
....
|
||||||
# Place text into clipboard
|
# Place text into clipboard
|
||||||
echo "command clipboard This text will be copied to clipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command clipboard This text will be copied to clipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Export clipboard to file
|
# Export clipboard to file
|
||||||
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
....
|
....
|
||||||
|
|
||||||
===== Application Control
|
===== Application Control
|
||||||
|
|
||||||
....
|
....
|
||||||
# Quit Fenrir
|
# Quit Fenrir
|
||||||
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
....
|
....
|
||||||
|
|
||||||
==== Command Reference
|
==== Command Reference
|
||||||
|
|||||||
+23
-21
@@ -143,68 +143,70 @@ enable_command_remote=True # allow command execution
|
|||||||
#### Instance Discovery
|
#### Instance Discovery
|
||||||
```bash
|
```bash
|
||||||
# List registered Fenrir instances and their socket paths
|
# List registered Fenrir instances and their socket paths
|
||||||
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
In X terminal mode (`fenrir -x`), multiple Fenrir instances can run at the same
|
In X terminal mode (`fenrir -x`), multiple Fenrir instances can run at the same
|
||||||
time. Each instance has a private socket at `/tmp/fenrirscreenreader-<pid>.sock`,
|
time. Each instance has a private socket at `/tmp/fenrirscreenreader-<pid>.sock`,
|
||||||
and one instance may also own the standard control socket. Use `ls` or
|
and one instance may also own the standard control socket. Use `ls` or
|
||||||
`command ls` on the standard socket to find the private socket for a specific
|
`command ls` on the standard socket to find the private socket for a specific
|
||||||
instance.
|
instance. Commands sent to the standard socket are handled by its owner when
|
||||||
|
possible; otherwise they are forwarded to a registered private socket,
|
||||||
|
preferring the sender's Fenrir ancestor when one can be found.
|
||||||
|
|
||||||
#### Speech Control
|
#### Speech Control
|
||||||
```bash
|
```bash
|
||||||
# Interrupt current speech
|
# Interrupt current speech
|
||||||
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Speak custom text
|
# Speak custom text
|
||||||
echo "command say Hello, this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say Hello, this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Temporarily disable speech
|
# Temporarily disable speech
|
||||||
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Settings Control
|
#### Settings Control
|
||||||
```bash
|
```bash
|
||||||
# Enable highlight tracking
|
# Enable highlight tracking
|
||||||
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change speech parameters
|
# Change speech parameters
|
||||||
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#pitch=0.6" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#pitch=0.6" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#volume=0.9" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#volume=0.9" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Change punctuation level (none/some/most/all)
|
# Change punctuation level (none/some/most/all)
|
||||||
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set general#punctuation_level=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Voice and TTS control
|
# Voice and TTS control
|
||||||
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting set speech#module=espeak-ng" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#module=espeak-ng" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Multiple settings at once
|
# Multiple settings at once
|
||||||
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Reset all settings
|
# Reset all settings
|
||||||
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Save settings
|
# Save settings
|
||||||
echo "setting save" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting save" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
echo "setting saveas /tmp/my-settings.conf" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "setting saveas /tmp/my-settings.conf" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Clipboard Operations
|
#### Clipboard Operations
|
||||||
```bash
|
```bash
|
||||||
# Add text to clipboard
|
# Add text to clipboard
|
||||||
echo "command clipboard Text to copy" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command clipboard Text to copy" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Export clipboard to file
|
# Export clipboard to file
|
||||||
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Application Control
|
#### Application Control
|
||||||
```bash
|
```bash
|
||||||
# Quit Fenrir
|
# Quit Fenrir
|
||||||
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
### Command Reference
|
### Command Reference
|
||||||
@@ -240,7 +242,7 @@ echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-dea
|
|||||||
#### Bash Helper Function
|
#### Bash Helper Function
|
||||||
```bash
|
```bash
|
||||||
fenrir_say() {
|
fenrir_say() {
|
||||||
echo "command say $1" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo "command say $1" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
}
|
}
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
@@ -253,7 +255,7 @@ import socket
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
def send_fenrir_command(command):
|
def send_fenrir_command(command):
|
||||||
socket_path = "/tmp/fenrirscreenreader-deamon.sock"
|
socket_path = "/tmp/fenrirscreenreader-daemon.sock"
|
||||||
if os.path.exists(socket_path):
|
if os.path.exists(socket_path):
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ class FenrirManager:
|
|||||||
os.unlink(pid_socket_file)
|
os.unlink(pid_socket_file)
|
||||||
|
|
||||||
# Clean up main socket only if it is stale (not active)
|
# Clean up main socket only if it is stale (not active)
|
||||||
main_socket_file = "/tmp/fenrirscreenreader-deamon.sock"
|
main_socket_file = "/tmp/fenrirscreenreader-daemon.sock"
|
||||||
if os.path.exists(main_socket_file):
|
if os.path.exists(main_socket_file):
|
||||||
try:
|
try:
|
||||||
test_sock = socket.socket(
|
test_sock = socket.socket(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
|
import struct
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
from fenrirscreenreader.core import debug
|
||||||
@@ -16,7 +17,7 @@ from fenrirscreenreader.core.eventData import FenrirEventType
|
|||||||
from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver
|
from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver
|
||||||
|
|
||||||
|
|
||||||
MAIN_SOCKET_FILE = "/tmp/fenrirscreenreader-deamon.sock"
|
MAIN_SOCKET_FILE = "/tmp/fenrirscreenreader-daemon.sock"
|
||||||
|
|
||||||
|
|
||||||
class driver(remoteDriver):
|
class driver(remoteDriver):
|
||||||
@@ -132,6 +133,131 @@ class driver(remoteDriver):
|
|||||||
return False
|
return False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _socket_file_for_socket(self, fenrir_sock):
|
||||||
|
for bound_sock, socket_file in self.bound_sockets:
|
||||||
|
if bound_sock == fenrir_sock:
|
||||||
|
return socket_file
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def _get_peer_pid(self, client_sock):
|
||||||
|
so_peercred = getattr(socket, "SO_PEERCRED", 17)
|
||||||
|
try:
|
||||||
|
creds = client_sock.getsockopt(
|
||||||
|
socket.SOL_SOCKET, so_peercred, struct.calcsize("3i")
|
||||||
|
)
|
||||||
|
pid, _uid, _gid = struct.unpack("3i", creds)
|
||||||
|
return pid
|
||||||
|
except OSError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _get_parent_pid(self, pid):
|
||||||
|
try:
|
||||||
|
with open(f"/proc/{pid}/stat", "r", encoding="utf-8") as proc_file:
|
||||||
|
stat_text = proc_file.read()
|
||||||
|
except OSError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
end_command = stat_text.rfind(")")
|
||||||
|
if end_command == -1:
|
||||||
|
return 0
|
||||||
|
stat_fields = stat_text[end_command + 2 :].split()
|
||||||
|
if len(stat_fields) < 2:
|
||||||
|
return 0
|
||||||
|
try:
|
||||||
|
return int(stat_fields[1])
|
||||||
|
except ValueError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _find_ancestor_private_socket(self, pid):
|
||||||
|
seen_pids = set()
|
||||||
|
while pid > 1 and pid not in seen_pids:
|
||||||
|
seen_pids.add(pid)
|
||||||
|
socket_file = f"/tmp/fenrirscreenreader-{pid}.sock"
|
||||||
|
if self._is_registered_private_socket(socket_file):
|
||||||
|
return socket_file
|
||||||
|
pid = self._get_parent_pid(pid)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def _is_registered_private_socket(self, socket_file):
|
||||||
|
for instance in remoteInstanceRegistry.list_instances():
|
||||||
|
if socket_file in instance.get("socket_files", []):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _get_registered_private_sockets(self):
|
||||||
|
socket_files = []
|
||||||
|
for instance in remoteInstanceRegistry.list_instances():
|
||||||
|
for socket_file in instance.get("socket_files", []):
|
||||||
|
if socket_file == MAIN_SOCKET_FILE:
|
||||||
|
continue
|
||||||
|
if socket_file in socket_files:
|
||||||
|
continue
|
||||||
|
socket_files.append(socket_file)
|
||||||
|
return socket_files
|
||||||
|
|
||||||
|
def _find_available_private_socket(self, preferred_socket=""):
|
||||||
|
socket_files = self._get_registered_private_sockets()
|
||||||
|
if preferred_socket and preferred_socket in socket_files:
|
||||||
|
socket_files.remove(preferred_socket)
|
||||||
|
socket_files.insert(0, preferred_socket)
|
||||||
|
|
||||||
|
for socket_file in socket_files:
|
||||||
|
if self._is_own_socket_file(socket_file):
|
||||||
|
return socket_file
|
||||||
|
if self._is_socket_active(socket_file):
|
||||||
|
return socket_file
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def _is_own_socket_file(self, socket_file):
|
||||||
|
return any(
|
||||||
|
socket_file == bound_socket_file
|
||||||
|
for _bound_sock, bound_socket_file in self.bound_sockets
|
||||||
|
)
|
||||||
|
|
||||||
|
def _has_own_private_socket(self):
|
||||||
|
return any(
|
||||||
|
bound_socket_file != MAIN_SOCKET_FILE
|
||||||
|
for _bound_sock, bound_socket_file in self.bound_sockets
|
||||||
|
)
|
||||||
|
|
||||||
|
def _forward_remote_to_socket(self, data, socket_file):
|
||||||
|
forward_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
forward_sock.settimeout(0.2)
|
||||||
|
forward_sock.connect(socket_file)
|
||||||
|
forward_sock.sendall((data + "\n").encode("utf-8"))
|
||||||
|
return True
|
||||||
|
except OSError as e:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"unixDriver watch_dog: Error forwarding remote data to "
|
||||||
|
+ socket_file
|
||||||
|
+ ": "
|
||||||
|
+ str(e),
|
||||||
|
debug.DebugLevel.ERROR,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
forward_sock.close()
|
||||||
|
|
||||||
|
def _route_main_socket_command(self, data, client_sock, socket_file):
|
||||||
|
if socket_file != MAIN_SOCKET_FILE:
|
||||||
|
return False
|
||||||
|
if not self._has_own_private_socket():
|
||||||
|
return False
|
||||||
|
|
||||||
|
peer_pid = self._get_peer_pid(client_sock)
|
||||||
|
ancestor_socket = ""
|
||||||
|
if peer_pid > 1:
|
||||||
|
ancestor_socket = self._find_ancestor_private_socket(peer_pid)
|
||||||
|
target_socket = self._find_available_private_socket(ancestor_socket)
|
||||||
|
if not target_socket:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self._is_own_socket_file(target_socket):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self._forward_remote_to_socket(data, target_socket)
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
for fenrir_sock in self.fenrirSocks:
|
for fenrir_sock in self.fenrirSocks:
|
||||||
try:
|
try:
|
||||||
@@ -152,7 +278,7 @@ class driver(remoteDriver):
|
|||||||
self.bound_sockets = []
|
self.bound_sockets = []
|
||||||
remoteInstanceRegistry.remove_instance()
|
remoteInstanceRegistry.remove_instance()
|
||||||
|
|
||||||
def _handle_client(self, client_sock, event_queue):
|
def _handle_client(self, client_sock, event_queue, socket_file=""):
|
||||||
try:
|
try:
|
||||||
rawdata = client_sock.recv(8129)
|
rawdata = client_sock.recv(8129)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -173,6 +299,9 @@ class driver(remoteDriver):
|
|||||||
client_sock.sendall((response["message"] + "\n").encode("utf-8"))
|
client_sock.sendall((response["message"] + "\n").encode("utf-8"))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self._route_main_socket_command(data, client_sock, socket_file):
|
||||||
|
return
|
||||||
|
|
||||||
event_queue.put(
|
event_queue.put(
|
||||||
{
|
{
|
||||||
"Type": FenrirEventType.remote_incomming,
|
"Type": FenrirEventType.remote_incomming,
|
||||||
@@ -188,7 +317,7 @@ class driver(remoteDriver):
|
|||||||
|
|
||||||
def watch_dog(self, active, event_queue):
|
def watch_dog(self, active, event_queue):
|
||||||
# echo "command say this is a test" | socat -
|
# echo "command say this is a test" | socat -
|
||||||
# UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
# UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
for socket_file, optional in self._get_socket_candidates():
|
for socket_file, optional in self._get_socket_candidates():
|
||||||
fenrir_sock = self._bind_socket(socket_file, optional)
|
fenrir_sock = self._bind_socket(socket_file, optional)
|
||||||
if fenrir_sock is None:
|
if fenrir_sock is None:
|
||||||
@@ -215,10 +344,11 @@ class driver(remoteDriver):
|
|||||||
continue
|
continue
|
||||||
for fenrir_sock in r:
|
for fenrir_sock in r:
|
||||||
client_sock, client_addr = fenrir_sock.accept()
|
client_sock, client_addr = fenrir_sock.accept()
|
||||||
|
socket_file = self._socket_file_for_socket(fenrir_sock)
|
||||||
# Ensure client socket is always closed to prevent resource
|
# Ensure client socket is always closed to prevent resource
|
||||||
# leaks
|
# leaks
|
||||||
try:
|
try:
|
||||||
self._handle_client(client_sock, event_queue)
|
self._handle_client(client_sock, event_queue, socket_file)
|
||||||
finally:
|
finally:
|
||||||
# Always close client socket, even if data processing fails
|
# Always close client socket, even if data processing fails
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ class TestRemoteDataFormat:
|
|||||||
"x11_window_id": "0x123",
|
"x11_window_id": "0x123",
|
||||||
"socket_files": [
|
"socket_files": [
|
||||||
"/tmp/fenrirscreenreader-123.sock",
|
"/tmp/fenrirscreenreader-123.sock",
|
||||||
"/tmp/fenrirscreenreader-deamon.sock",
|
"/tmp/fenrirscreenreader-daemon.sock",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
from unittest.mock import Mock, mock_open, patch
|
||||||
|
|
||||||
|
from fenrirscreenreader.remoteDriver import unixDriver
|
||||||
|
|
||||||
|
|
||||||
|
class FakeClientSocket:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.data = data
|
||||||
|
self.sent = b""
|
||||||
|
|
||||||
|
def recv(self, _size):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def sendall(self, data):
|
||||||
|
self.sent += data
|
||||||
|
|
||||||
|
|
||||||
|
def test_main_socket_routes_to_ancestor_private_socket(mock_environment):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
driver.bound_sockets = [
|
||||||
|
(Mock(), "/tmp/fenrirscreenreader-999.sock"),
|
||||||
|
(Mock(), unixDriver.MAIN_SOCKET_FILE),
|
||||||
|
]
|
||||||
|
client_sock = FakeClientSocket(b"command say routed")
|
||||||
|
event_queue = Mock()
|
||||||
|
|
||||||
|
with patch.object(driver, "_get_peer_pid", return_value=1234), patch.object(
|
||||||
|
driver,
|
||||||
|
"_find_ancestor_private_socket",
|
||||||
|
return_value="/tmp/fenrirscreenreader-222.sock",
|
||||||
|
), patch.object(
|
||||||
|
driver,
|
||||||
|
"_find_available_private_socket",
|
||||||
|
return_value="/tmp/fenrirscreenreader-222.sock",
|
||||||
|
), patch.object(
|
||||||
|
driver, "_forward_remote_to_socket", return_value=True
|
||||||
|
) as forward:
|
||||||
|
driver._handle_client(
|
||||||
|
client_sock, event_queue, unixDriver.MAIN_SOCKET_FILE
|
||||||
|
)
|
||||||
|
|
||||||
|
forward.assert_called_once_with(
|
||||||
|
"command say routed", "/tmp/fenrirscreenreader-222.sock"
|
||||||
|
)
|
||||||
|
event_queue.put.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_main_socket_routes_to_first_available_private_socket(
|
||||||
|
mock_environment,
|
||||||
|
):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
driver.bound_sockets = [
|
||||||
|
(Mock(), "/tmp/fenrirscreenreader-999.sock"),
|
||||||
|
(Mock(), unixDriver.MAIN_SOCKET_FILE),
|
||||||
|
]
|
||||||
|
client_sock = FakeClientSocket(b"command say fallback")
|
||||||
|
event_queue = Mock()
|
||||||
|
|
||||||
|
with patch.object(driver, "_get_peer_pid", return_value=1234), patch.object(
|
||||||
|
driver,
|
||||||
|
"_find_ancestor_private_socket",
|
||||||
|
return_value="",
|
||||||
|
), patch.object(
|
||||||
|
driver,
|
||||||
|
"_find_available_private_socket",
|
||||||
|
return_value="/tmp/fenrirscreenreader-333.sock",
|
||||||
|
), patch.object(
|
||||||
|
driver, "_forward_remote_to_socket", return_value=True
|
||||||
|
) as forward:
|
||||||
|
driver._handle_client(
|
||||||
|
client_sock, event_queue, unixDriver.MAIN_SOCKET_FILE
|
||||||
|
)
|
||||||
|
|
||||||
|
forward.assert_called_once_with(
|
||||||
|
"command say fallback", "/tmp/fenrirscreenreader-333.sock"
|
||||||
|
)
|
||||||
|
event_queue.put.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_main_socket_handles_command_locally_without_available_target(
|
||||||
|
mock_environment,
|
||||||
|
):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
client_sock = FakeClientSocket(b"command say local")
|
||||||
|
event_queue = Mock()
|
||||||
|
|
||||||
|
with patch.object(driver, "_get_peer_pid", return_value=1234), patch.object(
|
||||||
|
driver,
|
||||||
|
"_find_available_private_socket",
|
||||||
|
return_value="",
|
||||||
|
):
|
||||||
|
driver._handle_client(
|
||||||
|
client_sock, event_queue, unixDriver.MAIN_SOCKET_FILE
|
||||||
|
)
|
||||||
|
|
||||||
|
event_queue.put.assert_called_once_with(
|
||||||
|
{
|
||||||
|
"Type": unixDriver.FenrirEventType.remote_incomming,
|
||||||
|
"data": "command say local",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_vcsa_main_socket_owner_handles_command_locally(mock_environment):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
driver.bound_sockets = [(Mock(), unixDriver.MAIN_SOCKET_FILE)]
|
||||||
|
client_sock = FakeClientSocket(b"command say root")
|
||||||
|
event_queue = Mock()
|
||||||
|
|
||||||
|
with patch.object(driver, "_find_available_private_socket") as find_available:
|
||||||
|
driver._handle_client(
|
||||||
|
client_sock, event_queue, unixDriver.MAIN_SOCKET_FILE
|
||||||
|
)
|
||||||
|
|
||||||
|
find_available.assert_not_called()
|
||||||
|
event_queue.put.assert_called_once_with(
|
||||||
|
{
|
||||||
|
"Type": unixDriver.FenrirEventType.remote_incomming,
|
||||||
|
"data": "command say root",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_private_socket_handles_command_locally(mock_environment):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
client_sock = FakeClientSocket(b"command say private")
|
||||||
|
event_queue = Mock()
|
||||||
|
|
||||||
|
driver._handle_client(
|
||||||
|
client_sock, event_queue, "/tmp/fenrirscreenreader-222.sock"
|
||||||
|
)
|
||||||
|
|
||||||
|
event_queue.put.assert_called_once_with(
|
||||||
|
{
|
||||||
|
"Type": unixDriver.FenrirEventType.remote_incomming,
|
||||||
|
"data": "command say private",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_command_still_returns_response_from_main_socket(mock_environment):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
mock_environment["runtime"]["RemoteManager"] = Mock()
|
||||||
|
client_sock = FakeClientSocket(b"command list")
|
||||||
|
event_queue = Mock()
|
||||||
|
mock_environment["runtime"][
|
||||||
|
"RemoteManager"
|
||||||
|
].handle_remote_incomming_with_response.return_value = {
|
||||||
|
"success": True,
|
||||||
|
"message": "pid=1",
|
||||||
|
}
|
||||||
|
|
||||||
|
driver._handle_client(client_sock, event_queue, unixDriver.MAIN_SOCKET_FILE)
|
||||||
|
|
||||||
|
assert client_sock.sent == b"pid=1\n"
|
||||||
|
event_queue.put.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_parent_pid_parses_process_names_with_spaces():
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
|
||||||
|
stat_file = mock_open(
|
||||||
|
read_data="1234 (name with spaces) S 567 1 1 0 -1 0\n"
|
||||||
|
)
|
||||||
|
with patch("builtins.open", stat_file):
|
||||||
|
assert driver._get_parent_pid(1234) == 567
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_available_private_socket_prefers_ancestor_socket(
|
||||||
|
mock_environment,
|
||||||
|
):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"fenrirscreenreader.remoteDriver.unixDriver.remoteInstanceRegistry.list_instances",
|
||||||
|
return_value=[
|
||||||
|
{
|
||||||
|
"pid": 111,
|
||||||
|
"socket_files": ["/tmp/fenrirscreenreader-111.sock"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pid": 222,
|
||||||
|
"socket_files": ["/tmp/fenrirscreenreader-222.sock"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
), patch.object(driver, "_is_socket_active", return_value=True):
|
||||||
|
assert (
|
||||||
|
driver._find_available_private_socket(
|
||||||
|
"/tmp/fenrirscreenreader-222.sock"
|
||||||
|
)
|
||||||
|
== "/tmp/fenrirscreenreader-222.sock"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_available_private_socket_skips_main_socket(
|
||||||
|
mock_environment,
|
||||||
|
):
|
||||||
|
driver = unixDriver.driver()
|
||||||
|
driver.env = mock_environment
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"fenrirscreenreader.remoteDriver.unixDriver.remoteInstanceRegistry.list_instances",
|
||||||
|
return_value=[
|
||||||
|
{
|
||||||
|
"pid": 111,
|
||||||
|
"socket_files": [
|
||||||
|
unixDriver.MAIN_SOCKET_FILE,
|
||||||
|
"/tmp/fenrirscreenreader-111.sock",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
), patch.object(driver, "_is_socket_active", return_value=True):
|
||||||
|
assert (
|
||||||
|
driver._find_available_private_socket()
|
||||||
|
== "/tmp/fenrirscreenreader-111.sock"
|
||||||
|
)
|
||||||
+3
-2
@@ -1,8 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# shellcheck disable=SC2329
|
||||||
cleanup() {
|
cleanup() {
|
||||||
# Make sure Fenrir is restored on exit of this script
|
# Make sure Fenrir is restored on exit of this script
|
||||||
echo -n "setting set screen#suspendingScreen=" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo -n "setting set screen#suspendingScreen=" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call the cleanup function on exit of this script
|
# Call the cleanup function on exit of this script
|
||||||
@@ -20,7 +21,7 @@ if ! [[ "$term" =~ ^[1-9]+$ ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Suspend the current terminal for Fenrir
|
# Suspend the current terminal for Fenrir
|
||||||
echo -n "setting set screen#suspendingScreen=$term" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
|
echo -n "setting set screen#suspendingScreen=$term" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock
|
||||||
|
|
||||||
# Start the x session
|
# Start the x session
|
||||||
command startx
|
command startx
|
||||||
|
|||||||
Reference in New Issue
Block a user