diff options
author | June McEnroe <june@causal.agency> | 2019-10-26 18:14:10 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2019-10-26 18:14:10 -0400 |
commit | ea0a9f3c813eefd5d498a00c0c9d9785bbe5e2b2 (patch) | |
tree | c68217479423583a5e21546965a7a02a026b34c9 | |
parent | Require PASS before USER (diff) | |
download | pounce-ea0a9f3c813eefd5d498a00c0c9d9785bbe5e2b2.tar.gz pounce-ea0a9f3c813eefd5d498a00c0c9d9785bbe5e2b2.zip |
Implement graceful shutdown
Diffstat (limited to '')
-rw-r--r-- | bounce.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/bounce.c b/bounce.c index 8d9a4b5..0c2d1d7 100644 --- a/bounce.c +++ b/bounce.c @@ -16,8 +16,10 @@ #include <assert.h> #include <err.h> +#include <errno.h> #include <limits.h> #include <poll.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -28,6 +30,11 @@ #include "bounce.h" +static volatile sig_atomic_t signals[NSIG]; +static void signalHandler(int signal) { + signals[signal] = 1; +} + static struct { struct pollfd *fds; struct Client **clients; @@ -148,8 +155,16 @@ int main(int argc, char *argv[]) { } eventAdd(server, NULL); + signal(SIGINT, signalHandler); + signal(SIGTERM, signalHandler); + size_t clients = 0; - while (0 < poll(event.fds, event.len, -1)) { + for (;;) { + int nfds = poll(event.fds, event.len, -1); + if (nfds < 0 && errno != EINTR) err(EX_IOERR, "poll"); + if (signals[SIGINT] || signals[SIGTERM]) break; + if (nfds < 0) continue; + for (size_t i = 0; i < event.len; ++i) { short revents = event.fds[i].revents; if (!revents) continue; @@ -158,6 +173,8 @@ int main(int argc, char *argv[]) { int fd; struct tls *tls = listenAccept(&fd, event.fds[i].fd); eventAdd(fd, clientAlloc(tls)); + // FIXME: This should only be done after a successful client + // registration. if (!clients++) serverFormat("AWAY\r\n"); continue; } @@ -192,5 +209,13 @@ int main(int argc, char *argv[]) { } } } - err(EX_IOERR, "poll"); + + serverFormat("QUIT\r\n"); + for (size_t i = 0; i < event.len; ++i) { + if (event.clients[i]) { + clientFormat(event.clients[i], "ERROR :Disconnecting\r\n"); + clientFree(event.clients[i]); + } + close(event.fds[i].fd); + } } |