summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2016-12-12 10:37:40 -0500
committerRay Strode <rstrode@redhat.com>2016-12-12 10:38:10 -0500
commit87448650f98d1677772f73dd8b5796af68650941 (patch)
tree679baaaa39858f2cb6e1b49ac1edbb47e57b1f48
parent999b2d9cd1e17f3b6f69d654862d924023ece100 (diff)
downloadgdm-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.c43
-rw-r--r--daemon/gdm-xerrors.h5
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