From b2d6839a8c025698cd80118331f21fa4bb459f02 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Fri, 1 Apr 2022 21:24:22 +0200 Subject: sfeed_curses: don't use bitmasks to keep the states for signals Reported by Leon Fisher, thanks! "Each signal should have its own sig_atomic_t variable if you want to keep state for all of them independently." A similar issue was referenced in a OpenBSD tech mailinglist thread: https://marc.info/?l=openbsd-tech&m=162940120614641&w=2 --- sfeed_curses.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/sfeed_curses.c b/sfeed_curses.c index 52dba93..4f92115 100644 --- a/sfeed_curses.c +++ b/sfeed_curses.c @@ -172,8 +172,8 @@ static time_t comparetime; static char *urlfile, **urls; static size_t nurls; -enum Signals { SigChld = 1, SigHup = 2, SigInt = 4, SigTerm = 8, SigWinch = 16 }; -volatile sig_atomic_t sigstate = 0; /* bitmask state of received signals */ +volatile sig_atomic_t state_sigchld = 0, state_sighup = 0, state_sigint = 0; +volatile sig_atomic_t state_sigterm = 0, state_sigwinch = 0; static char *plumbercmd = "xdg-open"; /* env variable: $SFEED_PLUMBER */ static char *pipercmd = "sfeed_content"; /* env variable: $SFEED_PIPER */ @@ -1004,9 +1004,11 @@ lineeditor(void) ttywrite(&input[nchars]); nchars++; } else if (ch < 0) { - if (sigstate & SigInt) - sigstate &= ~SigInt; /* reset: do not handle it later */ - else if (!sigstate || (sigstate & (SigChld | SigWinch))) + if (state_sigint) + state_sigint = 0; /* reset: do not handle it later */ + else if (state_sighup || state_sigterm) + ; /* cancel prompt and handle these signals */ + else /* no signal, time-out or SIGCHLD or SIGWINCH */ continue; /* do not cancel: process signal later */ free(input); return NULL; /* cancel prompt */ @@ -1569,11 +1571,11 @@ void sighandler(int signo) { switch (signo) { - case SIGCHLD: sigstate |= SigChld; break; - case SIGHUP: sigstate |= SigHup; break; - case SIGINT: sigstate |= SigInt; break; - case SIGTERM: sigstate |= SigTerm; break; - case SIGWINCH: sigstate |= SigWinch; break; + case SIGCHLD: state_sigchld = 1; break; + case SIGHUP: state_sighup = 1; break; + case SIGINT: state_sigint = 1; break; + case SIGTERM: state_sigterm = 1; break; + case SIGWINCH: state_sigwinch = 1; break; } } @@ -2321,28 +2323,33 @@ nextpage: event: if (ch == EOF) goto end; - else if (ch == -3 && sigstate == 0) + else if (ch == -3 && !state_sigchld && !state_sighup && + !state_sigint && !state_sigterm && !state_sigwinch) continue; /* just a time-out, nothing to do */ /* handle signals in a particular order */ - if (sigstate & SigChld) { - sigstate &= ~SigChld; + if (state_sigchld) { + state_sigchld = 0; /* wait on child processes so they don't become a zombie, do not block the parent process if there is no status, ignore errors */ while (waitpid((pid_t)-1, NULL, WNOHANG) > 0) ; } - if (sigstate & (SigInt | SigTerm)) { + if (state_sigterm) { cleanup(); - _exit(128 + (sigstate & SigTerm ? SIGTERM : SIGINT)); + _exit(128 + SIGTERM); } - if (sigstate & SigHup) { - sigstate &= ~SigHup; + if (state_sigint) { + cleanup(); + _exit(128 + SIGINT); + } + if (state_sighup) { + state_sighup = 0; feeds_reloadall(); } - if (sigstate & SigWinch) { - sigstate &= ~SigWinch; + if (state_sigwinch) { + state_sigwinch = 0; resizewin(); updategeom(); } -- cgit v1.2.3