diff options
author | Curtis McEnroe | 2018-11-30 19:45:34 -0500 |
---|---|---|
committer | Curtis McEnroe | 2018-11-30 19:45:34 -0500 |
commit | 414f928ac58278188638f8146a28a5747909de7b (patch) | |
tree | 8b5cf159990d66d7379f44a69e1f87526d1474bb /event.c | |
parent | 9d769111aef9a3e6148bf8205c3556cc0c5a46a9 (diff) |
Handle signals consistently in the event loop
Diffstat (limited to 'event.c')
-rw-r--r-- | event.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/event.c b/event.c index 9f8c35e..f5d1f32 100644 --- a/event.c +++ b/event.c @@ -14,16 +14,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <err.h> +#include <errno.h> #include <poll.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <stdnoreturn.h> #include <string.h> #include <sys/wait.h> #include <sysexits.h> #include <unistd.h> -#include <errno.h> #include "chat.h" @@ -86,8 +88,7 @@ static void pipeRead(void) { } } -static void sigchld(int sig) { - (void)sig; +static void handleChild(void) { int status; pid_t pid = wait(&status); if (pid < 0) err(EX_OSERR, "wait"); @@ -99,16 +100,31 @@ static void sigchld(int sig) { spawn.wait = false; } -static void sigint(int sig) { - (void)sig; +static void handleInterrupt(void) { input(TagStatus, "/quit"); uiExit(); exit(EX_OK); } -void eventLoop(void) { - signal(SIGINT, sigint); - signal(SIGCHLD, sigchld); +static sig_atomic_t sig[NSIG]; +static void handler(int n) { + sig[n] = 1; +} + +noreturn void eventLoop(void) { + sigset_t mask; + sigemptyset(&mask); + struct sigaction sa = { + .sa_handler = handler, + .sa_mask = mask, + .sa_flags = SA_RESTART, + }; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + struct sigaction curses; + sigaction(SIGWINCH, &sa, &curses); + assert(!(curses.sa_flags & SA_SIGINFO)); int irc = ircConnect(); @@ -118,6 +134,17 @@ void eventLoop(void) { { -1, POLLIN, 0 }, }; for (;;) { + if (sig[SIGCHLD]) handleChild(); + if (sig[SIGINT]) handleInterrupt(); + if (sig[SIGWINCH]) { + curses.sa_handler(SIGWINCH); + uiRead(); + uiDraw(); + } + sig[SIGCHLD] = 0; + sig[SIGINT] = 0; + sig[SIGWINCH] = 0; + nfds_t nfds = 2; if (spawn.wait) nfds = 1; if (spawn.pipe) { @@ -127,10 +154,8 @@ void eventLoop(void) { int ready = poll(fds, nfds, -1); if (ready < 0) { - if (errno != EINTR) err(EX_IOERR, "poll"); - uiRead(); - uiDraw(); - continue; + if (errno == EINTR) continue; + err(EX_IOERR, "poll"); } if (fds[0].revents) ircRead(); |