summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@herrb.eu>2016-09-03 12:28:37 +0100
committerMatthieu Herrb <matthieu@herrb.eu>2016-09-03 12:28:37 +0100
commit3d0abf11f541b9bd75a2ea568f3ffca69fb48484 (patch)
tree3bde74f5b7235f3a2e72f7d17534327d0f6d6266
parentb4e20a0ac034538ef2cf01fce93ee80aea6c8a89 (diff)
Replace the last remaining setjmp()/longjmp() with ppoll().
-rw-r--r--xdm/server.c84
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");