diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 72 |
1 files changed, 66 insertions, 6 deletions
@@ -1,4 +1,10 @@ +/* As of FreeBSD 13.2, sigaction(2) still conforms to IEEE Std + * 1003.1-1990 (POSIX.1), which did not define SA_RESTART. + * FreeBSD supports it as an extension, but then _POSIX_C_SOURCE must + * not be defined. */ +#ifndef __FreeBSD__ #define _POSIX_C_SOURCE 200809L +#endif #include "auth.h" #include "cftw.h" @@ -18,6 +24,7 @@ #include <unistd.h> #include <errno.h> #include <limits.h> +#include <signal.h> #include <stdbool.h> #include <stddef.h> #include <stdio.h> @@ -32,6 +39,8 @@ struct form char *key, *value; }; +static struct handler *handler; + static int redirect(struct http_response *const r) { *r = (const struct http_response) @@ -2108,10 +2117,60 @@ static int add_urls(struct handler *const h, void *const user) return 0; } +static void handle_signal(const int signum) +{ + switch (signum) + { + case SIGINT: + /* Fall through. */ + case SIGTERM: + handler_notify_close(handler); + break; + + default: + break; + } +} + +static int init_signals(void) +{ + struct sigaction sa = + { + .sa_handler = handle_signal, + .sa_flags = SA_RESTART + }; + + sigemptyset(&sa.sa_mask); + + static const struct signal + { + int signal; + const char *name; + } signals[] = + { + {.signal = SIGINT, .name = "SIGINT"}, + {.signal = SIGTERM, .name = "SIGTERM"}, + {.signal = SIGPIPE, .name = "SIGPIPE"} + }; + + for (size_t i = 0; i < sizeof signals / sizeof *signals; i++) + { + const struct signal *const s = &signals[i]; + + if (sigaction(s->signal, &sa, NULL)) + { + fprintf(stderr, "%s: sigaction(2) %s: %s\n", + __func__, s->name, strerror(errno)); + return -1; + } + } + + return 0; +} + int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; - struct handler *h = NULL; struct auth *a = NULL; const char *dir, *tmpdir; unsigned short port; @@ -2138,14 +2197,15 @@ int main(int argc, char *argv[]) unsigned short outport; - if (!(h = handler_alloc(&cfg)) - || add_urls(h, a) - || handler_listen(h, port, &outport)) + if (!(handler = handler_alloc(&cfg)) + || add_urls(handler, a) + || init_signals() + || handler_listen(handler, port, &outport)) goto end; printf("Listening on port %hu\n", outport); - if (handler_loop(h)) + if (handler_loop(handler)) { fprintf(stderr, "%s: handler_loop failed\n", __func__); goto end; @@ -2155,6 +2215,6 @@ int main(int argc, char *argv[]) end: auth_free(a); - handler_free(h); + handler_free(handler); return ret; } |
