Fenrir was not cleaning up after itself properly. Fixed several possible stale file bugs and hopefully this problem is now gone.
This commit is contained in:
+5
-2
@@ -106,14 +106,17 @@ def run_fenrir():
|
|||||||
fenrirApp.proceed()
|
fenrirApp.proceed()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error starting Fenrir: {e}", file=sys.stderr)
|
print(f"Error starting Fenrir: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Interrupted", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
finally:
|
||||||
if fenrirApp and hasattr(fenrirApp, 'cleanup_on_error'):
|
if fenrirApp and hasattr(fenrirApp, 'cleanup_on_error'):
|
||||||
try:
|
try:
|
||||||
fenrirApp.cleanup_on_error()
|
fenrirApp.cleanup_on_error()
|
||||||
except Exception as cleanup_error:
|
except Exception as cleanup_error:
|
||||||
print(
|
print(
|
||||||
f"Error during cleanup: {cleanup_error}", file=sys.stderr)
|
f"Error during cleanup: {cleanup_error}", file=sys.stderr)
|
||||||
sys.exit(1)
|
|
||||||
finally:
|
|
||||||
if fenrirApp:
|
if fenrirApp:
|
||||||
del fenrirApp
|
del fenrirApp
|
||||||
# Clean up PID file if it exists
|
# Clean up PID file if it exists
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
@@ -40,6 +41,7 @@ class FenrirManager:
|
|||||||
# Set signal handlers after successful initialization
|
# Set signal handlers after successful initialization
|
||||||
signal.signal(signal.SIGINT, self.capture_signal)
|
signal.signal(signal.SIGINT, self.capture_signal)
|
||||||
signal.signal(signal.SIGTERM, self.capture_signal)
|
signal.signal(signal.SIGTERM, self.capture_signal)
|
||||||
|
signal.signal(signal.SIGHUP, self.capture_signal)
|
||||||
self.signal_handlers_set = True
|
self.signal_handlers_set = True
|
||||||
|
|
||||||
self.is_initialized = True
|
self.is_initialized = True
|
||||||
@@ -381,9 +383,15 @@ class FenrirManager:
|
|||||||
time.sleep(0.6)
|
time.sleep(0.6)
|
||||||
|
|
||||||
for currentManager in self.environment["general"]["managerList"]:
|
for currentManager in self.environment["general"]["managerList"]:
|
||||||
if self.environment["runtime"][currentManager]:
|
try:
|
||||||
|
if (
|
||||||
|
currentManager in self.environment["runtime"]
|
||||||
|
and self.environment["runtime"][currentManager]
|
||||||
|
):
|
||||||
self.environment["runtime"][currentManager].shutdown()
|
self.environment["runtime"][currentManager].shutdown()
|
||||||
del self.environment["runtime"][currentManager]
|
del self.environment["runtime"][currentManager]
|
||||||
|
except Exception:
|
||||||
|
pass # Ignore errors during individual manager shutdown
|
||||||
|
|
||||||
self.environment = None
|
self.environment = None
|
||||||
|
|
||||||
@@ -394,6 +402,7 @@ class FenrirManager:
|
|||||||
if self.signal_handlers_set:
|
if self.signal_handlers_set:
|
||||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
||||||
|
signal.signal(signal.SIGHUP, signal.SIG_DFL)
|
||||||
self.signal_handlers_set = False
|
self.signal_handlers_set = False
|
||||||
|
|
||||||
# Clean up any initialized managers
|
# Clean up any initialized managers
|
||||||
@@ -454,7 +463,6 @@ class FenrirManager:
|
|||||||
# Clean up socket files that might not be removed by the driver
|
# Clean up socket files that might not be removed by the driver
|
||||||
try:
|
try:
|
||||||
socket_file = None
|
socket_file = None
|
||||||
screen_driver = None
|
|
||||||
if (
|
if (
|
||||||
"runtime" in self.environment
|
"runtime" in self.environment
|
||||||
and "SettingsManager" in self.environment["runtime"]
|
and "SettingsManager" in self.environment["runtime"]
|
||||||
@@ -465,19 +473,9 @@ class FenrirManager:
|
|||||||
].get_setting("remote", "socket_file")
|
].get_setting("remote", "socket_file")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # Use default socket file path
|
pass # Use default socket file path
|
||||||
try:
|
|
||||||
screen_driver = self.environment["runtime"][
|
|
||||||
"SettingsManager"
|
|
||||||
].get_setting("screen", "driver")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not socket_file:
|
if not socket_file:
|
||||||
if screen_driver == "vcsaDriver":
|
# Always clean up PID-specific socket
|
||||||
socket_file = "/tmp/fenrirscreenreader-deamon.sock"
|
|
||||||
if os.path.exists(socket_file):
|
|
||||||
os.unlink(socket_file)
|
|
||||||
|
|
||||||
pid_socket_file = (
|
pid_socket_file = (
|
||||||
"/tmp/fenrirscreenreader-"
|
"/tmp/fenrirscreenreader-"
|
||||||
+ str(os.getpid())
|
+ str(os.getpid())
|
||||||
@@ -485,6 +483,20 @@ class FenrirManager:
|
|||||||
)
|
)
|
||||||
if os.path.exists(pid_socket_file):
|
if os.path.exists(pid_socket_file):
|
||||||
os.unlink(pid_socket_file)
|
os.unlink(pid_socket_file)
|
||||||
|
|
||||||
|
# Clean up main socket only if it is stale (not active)
|
||||||
|
main_socket_file = "/tmp/fenrirscreenreader-deamon.sock"
|
||||||
|
if os.path.exists(main_socket_file):
|
||||||
|
try:
|
||||||
|
test_sock = socket.socket(
|
||||||
|
socket.AF_UNIX, socket.SOCK_STREAM
|
||||||
|
)
|
||||||
|
test_sock.settimeout(0.2)
|
||||||
|
test_sock.connect(main_socket_file)
|
||||||
|
except OSError:
|
||||||
|
os.unlink(main_socket_file)
|
||||||
|
finally:
|
||||||
|
test_sock.close()
|
||||||
elif os.path.exists(socket_file):
|
elif os.path.exists(socket_file):
|
||||||
os.unlink(socket_file)
|
os.unlink(socket_file)
|
||||||
remoteInstanceRegistry.remove_instance()
|
remoteInstanceRegistry.remove_instance()
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ def write_instance(instance_data):
|
|||||||
registry_dir = get_registry_dir()
|
registry_dir = get_registry_dir()
|
||||||
os.makedirs(registry_dir, mode=0o755, exist_ok=True)
|
os.makedirs(registry_dir, mode=0o755, exist_ok=True)
|
||||||
os.chmod(registry_dir, 0o755)
|
os.chmod(registry_dir, 0o755)
|
||||||
|
prune_stale_instances()
|
||||||
instance_data["updated_at"] = time.time()
|
instance_data["updated_at"] = time.time()
|
||||||
instance_path = get_instance_file(instance_data.get("pid"))
|
instance_path = get_instance_file(instance_data.get("pid"))
|
||||||
with open(instance_path, "w", encoding="utf-8") as instance_file:
|
with open(instance_path, "w", encoding="utf-8") as instance_file:
|
||||||
@@ -53,6 +54,39 @@ def process_exists(pid):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def prune_stale_instances():
|
||||||
|
registry_dir = get_registry_dir()
|
||||||
|
try:
|
||||||
|
instance_files = os.listdir(registry_dir)
|
||||||
|
except FileNotFoundError:
|
||||||
|
return
|
||||||
|
|
||||||
|
now = time.time()
|
||||||
|
for instance_name in instance_files:
|
||||||
|
instance_path = os.path.join(registry_dir, instance_name)
|
||||||
|
try:
|
||||||
|
with open(instance_path, "r", encoding="utf-8") as instance_file:
|
||||||
|
instance_data = json.load(instance_file)
|
||||||
|
pid = int(instance_data.get("pid", 0))
|
||||||
|
updated_at = float(instance_data.get("updated_at", 0))
|
||||||
|
except (OSError, ValueError, TypeError, json.JSONDecodeError):
|
||||||
|
try:
|
||||||
|
os.unlink(instance_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (
|
||||||
|
not pid
|
||||||
|
or not process_exists(pid)
|
||||||
|
or now - updated_at > INSTANCE_TIMEOUT_SEC
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
os.unlink(instance_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def list_instances():
|
def list_instances():
|
||||||
registry_dir = get_registry_dir()
|
registry_dir = get_registry_dir()
|
||||||
instances = []
|
instances = []
|
||||||
@@ -72,7 +106,11 @@ def list_instances():
|
|||||||
except (OSError, ValueError, TypeError, json.JSONDecodeError):
|
except (OSError, ValueError, TypeError, json.JSONDecodeError):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not pid or not process_exists(pid) or now - updated_at > INSTANCE_TIMEOUT_SEC:
|
if (
|
||||||
|
not pid
|
||||||
|
or not process_exists(pid)
|
||||||
|
or now - updated_at > INSTANCE_TIMEOUT_SEC
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
os.unlink(instance_path)
|
os.unlink(instance_path)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
version = "2026.05.14"
|
version = "2026.05.18"
|
||||||
code_name = "testing"
|
code_name = "testing"
|
||||||
|
|||||||
Reference in New Issue
Block a user