#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. import os import os.path import select import socket from fenrirscreenreader.core import debug from fenrirscreenreader.core.eventData import FenrirEventType from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver 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)