#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver from fenrirscreenreader.core.eventData import FenrirEventType import select import socket import os import os.path class driver(remoteDriver): def __init__(self): remoteDriver.__init__(self) def initialize(self, environment): self.env = environment self.env['runtime']['ProcessManager'].add_custom_event_thread( self.watch_dog, multiprocess=True) def watch_dog(self, active, event_queue): # echo "command say this is a test" | socat - # UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock socket_file = '' try: socket_file = self.env['runtime']['SettingsManager'].get_setting( 'remote', 'socket_file') except Exception as e: self.env['runtime']['DebugManager'].write_debug_out( 'unixDriver watch_dog: Error getting socket file setting: ' + str(e), debug.DebugLevel.ERROR) if socket_file == '': if self.env['runtime']['SettingsManager'].get_setting( 'screen', 'driver') == 'vcsaDriver': socket_file = '/tmp/fenrirscreenreader-deamon.sock' else: socket_file = '/tmp/fenrirscreenreader-' + \ str(os.getppid()) + '.sock' if os.path.exists(socket_file): os.unlink(socket_file) self.fenrirSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.fenrirSock.bind(socket_file) os.chmod(socket_file, 0o666) # Allow all users to read/write self.fenrirSock.listen(1) while active.value: # Check if the client is still connected and if data is available: try: r, _, _ = select.select([self.fenrirSock], [], [], 0.8) except select.error: break if r == []: continue if self.fenrirSock in r: client_sock, client_addr = self.fenrirSock.accept() # Ensure client socket is always closed to prevent resource # leaks try: try: rawdata = client_sock.recv(8129) except Exception as e: self.env['runtime']['DebugManager'].write_debug_out( 'unixDriver watch_dog: Error receiving data from client: ' + str(e), debug.DebugLevel.ERROR) rawdata = b'' # Set default empty data if recv fails try: data = rawdata.decode("utf-8").rstrip().lstrip() event_queue.put({"Type": FenrirEventType.remote_incomming, "data": data }) except Exception as e: self.env['runtime']['DebugManager'].write_debug_out( 'unixDriver watch_dog: Error decoding/queuing data: ' + str(e), debug.DebugLevel.ERROR) finally: # Always close client socket, even if data processing fails try: client_sock.close() except Exception as e: self.env['runtime']['DebugManager'].write_debug_out( 'unixDriver watch_dog: Error closing client socket: ' + str(e), debug.DebugLevel.ERROR) if self.fenrirSock: self.fenrirSock.close() self.fenrirSock = None if os.path.exists(socket_file): os.unlink(socket_file)