The package includes a patch to fix seg-faults which can occur by
sending repeated SIGINTs or SIGTERMs.  However, it does this by
introducing a busy-wait loop which wakes the process up ten times a
second.

I've attached an updated version of it which uses a blocking select(2)
instead.

J.
Description: Avoid segfault when receiving CTRL-C twice.
Updated to replace busy-wait loop with nextEvent function using select(2).
Author: Kevin Kreamer <ke...@kreamer.org>
Author: Jeremy Sowden <jer...@azazel.net>
Bug-Debian: https://bugs.debian.org/599382
Bug-Debian: https://bugs.debian.org/872470
Last-Update: 2019-06-22

--- a/wmdrawer.c
+++ b/wmdrawer.c
@@ -44,7 +44,8 @@
 #include "pixmaps/defaultHighlightImg.xpm"
 
 static void signalHandler (int signum);
-static void quit (int status);
+static void setExit (int status);
+static void quit (void);
 static void xfreeAllMemory (void);
 static void buildDock (int argc, char *argv[]);
 static void setDockIcon (void);
@@ -80,6 +81,9 @@
 static unsigned int btnDim = 0;
 static int highlightCol, highlightRow;
 
+static int shouldExit;
+static int exitCode;
+
 extern drawerConfig config;
 extern unsigned int nbRows, nbCols, drawerOK;
 extern unsigned int useDefaultIconsBg, useDefaultDockIcon, useDefaultHighlightImg;
@@ -93,6 +97,8 @@
   setDockIcon ();
   buildDrawer ();
   buildTooltip ();
+  exitCode = EXIT_SUCCESS;
+  shouldExit = 0;
   action.sa_handler = signalHandler;
   sigemptyset (&action.sa_mask);
   action.sa_flags = SA_NOCLDSTOP | SA_NODEFER; 
@@ -101,29 +107,34 @@
   sigaction (SIGCHLD, &action, NULL);
 
   eventLoop ();
-  return 0;
+  quit ();
+  return exitCode;
 }
 
 static void signalHandler (int signum) {
   switch (signum) {
   case SIGINT:
   case SIGTERM:
-    quit (EXIT_SUCCESS);
+    setExit(EXIT_SUCCESS);
     break;
   case SIGCHLD:
     while (waitpid (-1, NULL, WNOHANG | WUNTRACED) > 0);
     break;
   default:
-    quit (EXIT_FAILURE);
+    setExit(EXIT_FAILURE);
   }
 }
 
-static void quit (int status) {
+static void setExit (int status) {
+    exitCode = status;
+    shouldExit = 1;
+}
+
+static void quit () {
   printf ("Bye bye, thx to use %s\n", PACKAGE);
   xfreeAllMemory ();
   freeAllMemory ();
   XCloseDisplay (display);
-  exit (status);
 }
 
 void xfreeAllMemory (void) {
@@ -825,6 +836,29 @@
   return 0;
 }
 
+static int nextEvent (XEvent *e) {
+  fd_set rset;
+
+  dbg_msg (1, "Enter nextEvent function\n");
+
+  XSync (display, False);
+  if (XPending (display)) {
+    XNextEvent (display, e);
+    dbg_msg (1, "Event type = %d\n", e->type);
+    return 1;
+  }
+
+  FD_ZERO (&rset);
+  FD_SET (ConnectionNumber (display), &rset);
+
+  if (select (ConnectionNumber (display)+1, &rset, NULL, NULL, NULL) > 0) {
+    XNextEvent (display, e);
+    return 1;
+  }
+
+  return 0;
+}
+
 /* Convert mouse coordinate into button coordinate */
 static void convertMCoordIntoBCoord (int mcol, int mrow, int *bcol, int *brow) {
   switch (config.direction) {
@@ -854,8 +888,11 @@
   int xbtn = 0, ybtn = 0;
   unsigned int delta, btnIsPressed = 0;
 
-  while (True) {
-    XNextEvent (display, &e);
+  while (shouldExit == 0) {
+    if (nextEvent(&e) == 0) {
+      continue;
+    }
+
     rebuildApp ();
     /* look at X.h & Xlib.h in /usr/X11R6/include/X11/ */
     switch (e.type) {
@@ -1012,7 +1049,7 @@
       }
       break;
     case DestroyNotify:
-      quit (EXIT_SUCCESS);
+      setExit(EXIT_SUCCESS);
     }
   }
 }

Attachment: signature.asc
Description: PGP signature

Reply via email to