From 328dada934b8e1488e09630b37e7bcadcd25fe66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 28 Feb 2023 00:58:57 +0100 Subject: [PATCH 1/2] gui-agent: die when xorg fails to start --- gui-agent/vmside.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/gui-agent/vmside.c b/gui-agent/vmside.c index 59ae535b..5291f4f9 100644 --- a/gui-agent/vmside.c +++ b/gui-agent/vmside.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +146,7 @@ struct genlist *windows_list; struct genlist *embeder_list; typedef struct _global_handles Ghandles; Ghandles *ghandles_for_vchan_reinitialize; +atomic_bool terminating; #define SKIP_NONMANAGED_WINDOW do { \ if (!list_lookup(windows_list, window)) { \ @@ -1976,13 +1979,32 @@ static pid_t do_execute_xorg( } } -static void terminate_and_cleanup_xorg(Ghandles *g) { +/* this cannot be a SIGCHLD signal handler because of signal safety */ +static void *xorg_waitpid_thread(void *p) { + Ghandles *g = p; int status; + waitpid(g->x_pid, &status, 0); + if (atomic_load(&terminating)) { + exit(0); + } else { + if (WIFEXITED(status)) { + fprintf(stderr, "Xorg exited unexpectedly (exit code %d)\n", + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "Xorg terminated unexpectedly (signal %d)\n", + WTERMSIG(status)); + } else { + fprintf(stderr, "Xorg terminated unexpectedly\n"); + } + exit(1); + } +} + +static void terminate_and_cleanup_xorg(Ghandles *g) { if (g->x_pid != (pid_t)-1) { + atomic_store(&terminating, true); kill(g->x_pid, SIGTERM); - waitpid(g->x_pid, &status, 0); - g->x_pid = -1; } } @@ -2185,7 +2207,7 @@ static void handle_sigterm() { Ghandles *g = ghandles_for_vchan_reinitialize; terminate_and_cleanup_xorg(g); - exit(0); + while (1) pause(); } static void usage() @@ -2253,6 +2275,7 @@ int main(int argc, char **argv) int xfd; Ghandles g; int wait_fds[2]; + pthread_t waitpid_thread; parse_args(&g, argc, argv); @@ -2274,6 +2297,10 @@ int main(int argc, char **argv) vchan_register_at_eof(handle_guid_disconnect); send_protocol_version(g.vchan); g.x_pid = get_xconf_and_run_x(&g); + if (pthread_create(&waitpid_thread, NULL, xorg_waitpid_thread, &g) < 0) { + perror("pthread_create"); + exit(1); + } mkghandles(&g); ghandles_for_vchan_reinitialize = &g; /* Turn on Composite for all children of root window. This way X server @@ -2315,7 +2342,6 @@ int main(int argc, char **argv) fprintf(stderr, "XFixes not available, cursor shape handling off"); XAutoRepeatOff(g.display); - signal(SIGCHLD, SIG_IGN); signal(SIGTERM, handle_sigterm); windows_list = list_new(); embeder_list = list_new(); From d29eb36a8c88a7040b96735cfe8b36f7b1a669f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 7 Mar 2023 21:57:52 +0100 Subject: [PATCH 2/2] fixup! gui-agent: die when xorg fails to start --- gui-agent/vmside.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/gui-agent/vmside.c b/gui-agent/vmside.c index 5291f4f9..7bf2b2db 100644 --- a/gui-agent/vmside.c +++ b/gui-agent/vmside.c @@ -1983,7 +1983,15 @@ static pid_t do_execute_xorg( static void *xorg_waitpid_thread(void *p) { Ghandles *g = p; int status; - waitpid(g->x_pid, &status, 0); + while (waitpid(g->x_pid, &status, 0) < 0) { + if (errno != EINTR) { + /* Looking at waitpid(2), everything other than EINTR would + * indicate a logic error; log this and give up. */ + perror("waitpid"); + abort(); + } + } + if (atomic_load(&terminating)) { exit(0); } else { @@ -2297,8 +2305,9 @@ int main(int argc, char **argv) vchan_register_at_eof(handle_guid_disconnect); send_protocol_version(g.vchan); g.x_pid = get_xconf_and_run_x(&g); - if (pthread_create(&waitpid_thread, NULL, xorg_waitpid_thread, &g) < 0) { + if ((errno = pthread_create(&waitpid_thread, NULL, xorg_waitpid_thread, &g)) != 0) { perror("pthread_create"); + kill(g.x_pid, SIGTERM); exit(1); } mkghandles(&g);