From c467ba6b0437efa44325c73ec974e848b0be96a8 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 19 Jul 2018 08:04:28 +0100 Subject: [PATCH] Add handler for fatal X server conditions Unless X server failures are caught, these can cause a premature exit of chansrv, giving it no chance to clean up. This is currently a particular problem for fuser mounts. --- sesman/chansrv/chansrv.c | 13 +++++++++++++ sesman/chansrv/xcommon.c | 25 ++++++++++++++++++++----- sesman/chansrv/xcommon.h | 4 ++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 34aa3f51..6ec05e53 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -1278,6 +1278,16 @@ segfault_signal_handler(int sig) exit(0); } +/*****************************************************************************/ +static void +x_server_fatal_handler(void) +{ + LOGM((LOG_LEVEL_INFO, "xserver_fatal_handler: entered.......")); + /* At this point the X server has gone away. Dont make any X calls. */ + xfuse_deinit(); + exit(0); +} + /*****************************************************************************/ static int get_display_num_from_display(char *display_text) @@ -1576,6 +1586,9 @@ main(int argc, char **argv) g_signal_child_stop(child_signal_handler); /* SIGCHLD */ g_signal_segfault(segfault_signal_handler); + /* Cater for the X server exiting unexpectedly */ + xcommon_set_x_server_fatal_handler(x_server_fatal_handler); + LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); if (g_display_num == 0) diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 8abc27f7..a995b3fc 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -28,6 +28,7 @@ #include "log.h" #include "clipboard.h" #include "rail.h" +#include "xcommon.h" /* #undef LOG_LEVEL @@ -50,6 +51,9 @@ Atom g_utf8_string = 0; Atom g_net_wm_name = 0; Atom g_wm_state = 0; +static x_server_fatal_cb_type x_server_fatal_handler = 0; + + /*****************************************************************************/ static int xcommon_error_handler(Display *dis, XErrorEvent *xer) @@ -64,16 +68,27 @@ xcommon_error_handler(Display *dis, XErrorEvent *xer) } /*****************************************************************************/ -/* The X server had an internal error. This is the last function called. - Do any cleanup that needs to be done on exit, like removing temporary files. +/* Allow the caller to be notified on X server failure + Specified callback can do any cleanup that needs to be done on exit, + like removing temporary files. This is the last function called. Don't worry about memory leaks */ -#if 0 +void +xcommon_set_x_server_fatal_handler(x_server_fatal_cb_type handler) +{ + x_server_fatal_handler = handler; +} + +/*****************************************************************************/ +/* The X server had an internal error */ static int xcommon_fatal_handler(Display *dis) { + if (x_server_fatal_handler) + { + x_server_fatal_handler(); + } return 0; } -#endif /*****************************************************************************/ /* returns time in milliseconds @@ -110,7 +125,7 @@ xcommon_init(void) /* setting the error handlers can cause problem when shutting down chansrv on some xlibs */ XSetErrorHandler(xcommon_error_handler); - //XSetIOErrorHandler(xcommon_fatal_handler); + XSetIOErrorHandler(xcommon_fatal_handler); g_x_socket = XConnectionNumber(g_display); diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h index ea74b89f..540abe74 100644 --- a/sesman/chansrv/xcommon.h +++ b/sesman/chansrv/xcommon.h @@ -26,6 +26,8 @@ #define FORMAT_TO_BYTES(_format) \ (_format) == 32 ? sizeof(long) : (_format) / 8 +typedef void (*x_server_fatal_cb_type)(void); + int xcommon_get_local_time(void); int @@ -34,5 +36,7 @@ int xcommon_get_wait_objs(tbus* objs, int* count, int* timeout); int xcommon_check_wait_objs(void); +void +xcommon_set_x_server_fatal_handler(x_server_fatal_cb_type handler); #endif