diff options
| author | AAGaming <aagaming@riseup.net> | 2024-08-06 23:25:39 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-06 20:25:39 -0700 |
| commit | 166c7ea8a7ea74d9a61d84ebe16556cec9e7cc83 (patch) | |
| tree | 884b3ec5e5bb4e11189eb0cc865b4896421af450 /backend/decky_loader/localplatform/localplatformlinux.py | |
| parent | ddc807340c6d65949c5ddcd665c77beb79edb38e (diff) | |
| download | decky-loader-166c7ea8a7ea74d9a61d84ebe16556cec9e7cc83.tar.gz decky-loader-166c7ea8a7ea74d9a61d84ebe16556cec9e7cc83.zip | |
Work around account switching failing to open the CEF debugger socket (#668)v3.0.0-pre6
* Work around account switching failing to open the CEF debugger socket
this automates lsof and gdb to force close the socket before steam finishes shutting down (from RegisterForShutdownStart)
* lint
* fix LD_LIBRARY_PATH for gdb
Diffstat (limited to 'backend/decky_loader/localplatform/localplatformlinux.py')
| -rw-r--r-- | backend/decky_loader/localplatform/localplatformlinux.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/backend/decky_loader/localplatform/localplatformlinux.py b/backend/decky_loader/localplatform/localplatformlinux.py index f22cb465..2c92124f 100644 --- a/backend/decky_loader/localplatform/localplatformlinux.py +++ b/backend/decky_loader/localplatform/localplatformlinux.py @@ -1,3 +1,5 @@ +from re import compile +from asyncio import Lock import os, pwd, grp, sys, logging from subprocess import call, run, DEVNULL, PIPE, STDOUT from ..enums import UserType @@ -227,3 +229,39 @@ def get_unprivileged_user() -> str: user = 'deck' return user + +# Works around the CEF debugger TCP socket not closing properly when Steam restarts +# Group 1 is PID, group 2 is FD. this also filters for "steamwebhelper" in the process name. +cef_socket_lsof_regex = compile(r"^p(\d+)(?:\s|.)+csteamwebhelper(?:\s|.)+f(\d+)(?:\s|.)+TST=LISTEN") +close_cef_socket_lock = Lock() + +async def close_cef_socket(): + async with close_cef_socket_lock: + if _get_effective_user_id() != 0: + logger.warn("Can't close CEF socket as Decky isn't running as root.") + return + # Look for anything listening TCP on port 8080 + lsof = run(["lsof", "-F", "-iTCP:8080", "-sTCP:LISTEN"], capture_output=True, text=True) + if lsof.returncode != 0 or len(lsof.stdout) < 1: + logger.error(f"lsof call failed in close_cef_socket! return code: {str(lsof.returncode)}") + return + + lsof_data = cef_socket_lsof_regex.match(lsof.stdout) + + if not lsof_data: + logger.error("lsof regex match failed in close_cef_socket!") + return + + pid = lsof_data.group(1) + fd = lsof_data.group(2) + + logger.info(f"Closing CEF socket with PID {pid} and FD {fd}") + + # Use gdb to inject a close() call for the socket fd into steamwebhelper + gdb_ret = run(["gdb", "--nx", "-p", pid, "--batch", "--eval-command", f"call (int)close({fd})"], env={"LD_LIBRARY_PATH": ""}) + + if gdb_ret.returncode != 0: + logger.error(f"Failed to close CEF socket with gdb! return code: {str(gdb_ret.returncode)}", exc_info=True) + return + + logger.info("CEF socket closed") |
