All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 9/9] pppd: refactor setjmp/longjmp with pipe pair in event wait loop
@ 2019-09-26  7:21 Kurt Van Dijck
  0 siblings, 0 replies; only message in thread
From: Kurt Van Dijck @ 2019-09-26  7:21 UTC (permalink / raw)
  To: linux-ppp

setjmp/longjmp isn't supported by all compilers.
Having a pipe pair to wake an event wait loop from within a signal handler
is rather portable and common enough.

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 pppd/main.c | 41 +++++++++++++++++++++++++----------------
 pppd/tty.c  |  1 -
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/pppd/main.c b/pppd/main.c
index b0d772b..41be532 100644
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -80,7 +80,6 @@
 #include <netdb.h>
 #include <utmp.h>
 #include <pwd.h>
-#include <setjmp.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -180,7 +179,7 @@ int got_sighup;
 
 static sigset_t signals_handled;
 static int waiting;
-static sigjmp_buf sigjmp;
+static int sigpipe[2];
 
 char **script_env;		/* Env. variable values for scripts */
 int s_env_nalloc;		/* # words avail at script_env */
@@ -598,19 +597,21 @@ static void
 handle_events()
 {
     struct timeval timo;
+    unsigned char buf[16];
 
     kill_link = open_ccp_flag = 0;
-    if (sigsetjmp(sigjmp, 1) = 0) {
-	sigprocmask(SIG_BLOCK, &signals_handled, NULL);
-	if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
-	    sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
-	} else {
-	    waiting = 1;
-	    sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
-	    wait_input(timeleft(&timo));
-	}
-    }
+
+    /* alert via signal pipe */
+    waiting = 1;
+    /* flush signal pipe */
+    for (; read(sigpipe[0], buf, sizeof(buf)) > 0; );
+    add_fd(sigpipe[0]);
+    /* wait if necessary */
+    if (!(got_sighup || got_sigterm || got_sigusr2 || got_sigchld))
+	wait_input(timeleft(&timo));
     waiting = 0;
+    remove_fd(sigpipe[0]);
+
     calltimeout();
     if (got_sighup) {
 	info("Hangup (SIGHUP)");
@@ -645,6 +646,14 @@ setup_signals()
 {
     struct sigaction sa;
 
+    /* create pipe to wake up event handler from signal handler */
+    if (pipe(sigpipe) < 0)
+	fatal("Couldn't create signal pipe: %m");
+    fcntl(sigpipe[0], F_SETFD, fcntl(sigpipe[0], F_GETFD) | FD_CLOEXEC);
+    fcntl(sigpipe[1], F_SETFD, fcntl(sigpipe[1], F_GETFD) | FD_CLOEXEC);
+    fcntl(sigpipe[0], F_SETFL, fcntl(sigpipe[0], F_GETFL) | O_NONBLOCK);
+    fcntl(sigpipe[1], F_SETFL, fcntl(sigpipe[1], F_GETFL) | O_NONBLOCK);
+
     /*
      * Compute mask of all interesting signals and install signal handlers
      * for each.  Only one signal handler may be active at a time.  Therefore,
@@ -1431,7 +1440,7 @@ hup(sig)
 	kill_my_pg(sig);
     notify(sigreceived, sig);
     if (waiting)
-	siglongjmp(sigjmp, 1);
+	write(sigpipe[1], &sig, sizeof(sig));
 }
 
 
@@ -1452,7 +1461,7 @@ term(sig)
 	kill_my_pg(sig);
     notify(sigreceived, sig);
     if (waiting)
-	siglongjmp(sigjmp, 1);
+	write(sigpipe[1], &sig, sizeof(sig));
 }
 
 
@@ -1466,7 +1475,7 @@ chld(sig)
 {
     got_sigchld = 1;
     if (waiting)
-	siglongjmp(sigjmp, 1);
+	write(sigpipe[1], &sig, sizeof(sig));
 }
 
 
@@ -1501,7 +1510,7 @@ open_ccp(sig)
 {
     got_sigusr2 = 1;
     if (waiting)
-	siglongjmp(sigjmp, 1);
+	write(sigpipe[1], &sig, sizeof(sig));
 }
 
 
diff --git a/pppd/tty.c b/pppd/tty.c
index c9a0b33..7ece675 100644
--- a/pppd/tty.c
+++ b/pppd/tty.c
@@ -83,7 +83,6 @@
 #include <netdb.h>
 #include <utmp.h>
 #include <pwd.h>
-#include <setjmp.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-- 
1.8.5.rc3

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-09-26  7:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-26  7:21 [PATCH 9/9] pppd: refactor setjmp/longjmp with pipe pair in event wait loop Kurt Van Dijck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.