diff options
author | Matthieu Herrb <matthieu@herrb.eu> | 2016-09-03 12:28:37 +0100 |
---|---|---|
committer | Matthieu Herrb <matthieu@herrb.eu> | 2016-09-03 12:28:37 +0100 |
commit | 3d0abf11f541b9bd75a2ea568f3ffca69fb48484 (patch) | |
tree | 3bde74f5b7235f3a2e72f7d17534327d0f6d6266 | |
parent | b4e20a0ac034538ef2cf01fce93ee80aea6c8a89 (diff) |
Replace the last remaining setjmp()/longjmp() with ppoll().
-rw-r--r-- | xdm/server.c | 84 |
1 files changed, 36 insertions, 48 deletions
diff --git a/xdm/server.c b/xdm/server.c index 0b4f549..b4bc6e1 100644 --- a/xdm/server.c +++ b/xdm/server.c @@ -139,66 +139,54 @@ StartServer (struct display *d) * the sleep finishes, 0 else */ -static Jmp_buf pauseAbort; -static int serverPauseRet; - -/* ARGSUSED */ -static SIGVAL -serverPauseAbort (int n) +void +chldHandler(int num) { - Longjmp (pauseAbort, 1); + Debug("a child died\n"); + return; } -/* ARGSUSED */ -static SIGVAL -serverPauseUsr1 (int n) -{ - Debug ("display manager paused til SIGUSR1\n"); - ++receivedUsr1; - Longjmp (pauseAbort, 1); -} +static int serverPauseRet; static int serverPause (unsigned t, pid_t serverPid) { + struct timespec timeout; + sigset_t mask; + int result; pid_t pid; serverPauseRet = 0; - if (!Setjmp (pauseAbort)) { - (void) signal (SIGALRM, serverPauseAbort); - (void) signal (SIGUSR1, serverPauseUsr1); - if (!receivedUsr1) - (void) alarm (t); - else + + for (;;) { + timeout.tv_sec = t; + timeout.tv_nsec = 0; + + /* setup a SIGCHLD handler, to interrupt ppoll() below */ + signal(SIGCHLD, chldHandler); + /* unblock all signals*/ + sigemptyset(&mask); + if (!receivedUsr1) { + result = ppoll(NULL, 0, &timeout, &mask); + if (result != -1 || errno != EINTR) + Debug("Timeout waiting for USR1\n"); + } else Debug ("Already received USR1\n"); - for (;;) { - /* - * wait() is unsafe. Other Xserver or xdm processes may - * exit at this time and this will remove the wait status. - * This means the main loop will not restart the display. - */ - if (!receivedUsr1) - pid = waitpid (serverPid, (int *) 0, 0); - else - pid = waitpid (serverPid, (int *) 0, WNOHANG); - - if (pid == serverPid || - (pid == -1 && errno == ECHILD)) - { - Debug ("Server dead\n"); - serverPauseRet = 1; - break; - } - - if (pid == 0) { - Debug ("Server alive and kicking\n"); - break; - } - } + + pid = waitpid (serverPid, (int *) 0, WNOHANG); + + if (pid == serverPid || + (pid == -1 && errno == ECHILD)) { + Debug ("Server dead\n"); + serverPauseRet = 1; + break; + } + if (pid == 0) { + Debug ("Server alive and kicking\n"); + break; + } } - (void) alarm ((unsigned) 0); - (void) signal (SIGALRM, SIG_DFL); - (void) signal (SIGUSR1, CatchUsr1); + signal(SIGCHLD, SIG_DFL); if (serverPauseRet) { Debug ("Server died\n"); LogError ("server unexpectedly died\n"); |