Clean up stale Wayland socket on shutdown, crash, and startup

This commit is contained in:
Andrew Hamilton 2026-08-09 12:02:21 +10:00
parent b80871c62c
commit 18653c9031

View file

@ -166,6 +166,7 @@ struct tabbed_host {
static struct tabbed_server server;
static struct tabbed_host host;
static char tabbed_socket[64];
static char socket_path[256];
static volatile sig_atomic_t needs_redraw;
static bool frame_pending;
static bool shutting_down;
@ -248,6 +249,18 @@ static void terminate_clients(void) {
}
}
/* Remove the session's Wayland socket file (and its companion .lock file,
both created by wl_display_add_socket), if present. The full path is
precomputed at startup so this only ever calls unlink()/snprintf(), which
are async-signal-safe and therefore safe from the signal/crash handlers
too. A missing file is fine: ENOENT is ignored, i.e. nothing to clean. */
static void remove_socket_file(void) {
unlink(socket_path);
char lock_path[sizeof(socket_path) + 6];
snprintf(lock_path, sizeof(lock_path), "%s.lock", socket_path);
unlink(lock_path);
}
/* Full shutdown of the nested session: take down the clients first, then
free our own allocations and exit. Guarded so the various close paths
(host window close, last tab closed) only run once. */
@ -261,6 +274,7 @@ static void shutdown_cleanup(void) {
}
if (server.xkb_keymap) xkb_keymap_unref(server.xkb_keymap);
if (server.xkb_ctx) xkb_context_unref(server.xkb_ctx);
remove_socket_file();
}
/* ===================== EGL helpers ===================== */
@ -1924,6 +1938,7 @@ static void crash_handler(int sig, siginfo_t *info, void *ctx) {
int n = backtrace(bt, 64);
write(2, "\n=== BACKTRACE ===\n", 19);
backtrace_symbols_fd(bt, n, 2);
remove_socket_file();
_exit(139);
}
@ -1963,6 +1978,12 @@ static void sigusr1_handler(int sig) {
int main(int argc, char *argv[]) {
snprintf(tabbed_socket, sizeof(tabbed_socket), "tabbed-wayland-%d",
(int)getpid());
const char *runtime = getenv("XDG_RUNTIME_DIR");
if (!runtime) runtime = "/tmp";
snprintf(socket_path, sizeof(socket_path), "%s/%s", runtime, tabbed_socket);
/* Clear a stale leftover (e.g. from a crashed previous run with the same
name) before we try to bind; harmless if there is none. */
remove_socket_file();
/* Resolve TABBED_LOG up front so signal handlers can read the cached
level without touching non-async-signal-safe functions. */
@ -2092,6 +2113,7 @@ int main(int argc, char *argv[]) {
/* Now connect to the host compositor and present inside it. */
if (!host_init()) {
fprintf(stderr, "tabbed-wlroots: could not start nested session\n");
remove_socket_file();
return 1;
}
@ -2104,6 +2126,7 @@ int main(int argc, char *argv[]) {
"takes args, e.g. \"firefox -no-remote\".\n"
" Arguments written bare (starting with '-') launch a "
"bogus extra tab.\n", argv[0]);
remove_socket_file();
return 1;
}
if (total_apps > MAX_APPS) total_apps = MAX_APPS;