From 78eff0cfa55606ade2ce494258739514c92994ca Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Thu, 22 Aug 2024 02:21:15 +0200 Subject: Bump to libweb 0.4.0 Now, libweb (rightfully) forces applications to handle signals and introduces handler_notify_close(3) to achieve the desired behaviour. Additionally, libweb 0.4.0 introduces several bugfixes. --- libweb | 2 +- main.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/libweb b/libweb index b4930f7..9357155 160000 --- a/libweb +++ b/libweb @@ -1 +1 @@ -Subproject commit b4930f72bb9026c5a0871f4fa4cabe20cb0e6a9f +Subproject commit 93571556ee97e1a3e1829f8bc708d1d63f188840 diff --git a/main.c b/main.c index 19590ad..3959295 100644 --- a/main.c +++ b/main.c @@ -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 #include #include +#include #include #include #include @@ -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; } -- cgit v1.2.3