diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index c1f7c04d7..706b5209d 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -1079,6 +1079,30 @@ def _probe_launchd_service_running() -> bool: return result.returncode == 0 +_FREEBSD_RCD_SERVICE = "hermes_daemon" + + +def _freebsd_rcd_service_path() -> Path: + return Path("/usr/local/etc/rc.d") / _FREEBSD_RCD_SERVICE + + +def _probe_freebsd_service_running() -> bool: + if not _freebsd_rcd_service_path().exists(): + return False + try: + # `onestatus` reports running state regardless of the rcvar enable flag, + # and works without root. + result = subprocess.run( + ["service", _FREEBSD_RCD_SERVICE, "onestatus"], + capture_output=True, + text=True, + timeout=10, + ) + except (subprocess.TimeoutExpired, FileNotFoundError, OSError): + return False + return result.returncode == 0 + + def get_gateway_runtime_snapshot(system: bool = False) -> GatewayRuntimeSnapshot: """Return a unified view of gateway liveness for the current profile.""" gateway_pids = tuple(find_gateway_pids()) @@ -1128,6 +1152,15 @@ def get_gateway_runtime_snapshot(system: bool = False) -> GatewayRuntimeSnapshot service_scope="launchd", ) + if is_freebsd(): + return GatewayRuntimeSnapshot( + manager=f"rc.d ({_FREEBSD_RCD_SERVICE})", + service_installed=_freebsd_rcd_service_path().exists(), + service_running=_probe_freebsd_service_running(), + gateway_pids=gateway_pids, + service_scope="rc.d", + ) + return GatewayRuntimeSnapshot( manager="manual process", gateway_pids=gateway_pids, @@ -1369,6 +1402,10 @@ def is_macos() -> bool: return sys.platform == "darwin" +def is_freebsd() -> bool: + return sys.platform.startswith("freebsd") + + def is_windows() -> bool: return sys.platform == "win32"