diff options
author | Ray Strode <rstrode@redhat.com> | 2016-12-12 10:37:40 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2016-12-12 10:38:10 -0500 |
commit | 87448650f98d1677772f73dd8b5796af68650941 (patch) | |
tree | 679baaaa39858f2cb6e1b49ac1edbb47e57b1f48 | |
parent | 999b2d9cd1e17f3b6f69d654862d924023ece100 (diff) | |
download | gdm-wip/longjmp-off-a-short-bridge.tar.gz |
wip! Add some gross longjmp code that I don't want to usewip/longjmp-off-a-short-bridge
-rw-r--r-- | daemon/gdm-xerrors.c | 43 | ||||
-rw-r--r-- | daemon/gdm-xerrors.h | 5 |
2 files changed, 47 insertions, 1 deletions
diff --git a/daemon/gdm-xerrors.c b/daemon/gdm-xerrors.c index 44f567ee..1fdfbc25 100644 --- a/daemon/gdm-xerrors.c +++ b/daemon/gdm-xerrors.c @@ -24,6 +24,7 @@ #include <glib/gstdio.h> #include <errno.h> #include <stdlib.h> +#include <setjmp.h> #include "gdm-xerrors.h" @@ -36,6 +37,11 @@ struct _GdmErrorTrap int error_code; }; +struct _GdmIOErrorTrap +{ + int (*old_handler) (Display *); +}; + static int gdm_x_error (Display *display, XErrorEvent *error); static int gdm_x_io_error (Display *display); @@ -47,7 +53,6 @@ static GSList *gdm_error_trap_free_list = NULL; /* Free list */ static int _gdm_error_warnings = TRUE; static int _gdm_error_code = 0; - void gdm_xerrors_init (void) { @@ -240,3 +245,39 @@ gdm_error_trap_pop (void) return result; } + +static jmp_buf gdm_jmp_buf; + +static enum { + NO_EXCEPTION = 0, + EXCEPTION = 1, + FINISHED = 2 +} gdm_jmp_state; + +#define TRY if ((gdm_jmp_state = setjmp (gdm_jmp_buf)) == NO_EXCEPTION) +#define EXCEPT if (gdm_jmp_state == NO_EXCEPTION) longjmp (gdm_jmp_buf, FINISHED); else + +#define THROW() longjmp (gdm_jmp_buf, EXCEPTION) + +static int +gdm_trapped_x_io_error (Display *display) +{ + THROW (); +} + +void +gdm_trap_xserver_hangup (GdmTrappedFunc trapped_func, + gpointer data) +{ + int (*old_handler) (Display *) = NULL; + + TRY { + old_handler = XSetIOErrorHandler (gdm_trapped_x_io_error); + + trapped_func (data); + + XSetIOErrorHandler (old_handler); + } EXCEPT { + XSetIOErrorHandler (old_handler); + } +} diff --git a/daemon/gdm-xerrors.h b/daemon/gdm-xerrors.h index fc7981e6..d2208a1e 100644 --- a/daemon/gdm-xerrors.h +++ b/daemon/gdm-xerrors.h @@ -31,9 +31,14 @@ typedef void (* GdmXErrorHandler) (Display *dpy, XErrorEvent *error, gpointer data); +typedef void (* GdmTrappedFunc) (gpointer *data); + void gdm_xerrors_init (void); void gdm_error_trap_push (void); gint gdm_error_trap_pop (void); +void gdm_trap_xserver_hangup (GdmTrappedFunc trapped_func, + gpointer data); + #endif |