commit 02621f745a3a9f8c2a809a8bceededa935c6f6d6
parent 07e37a1d06da433b3beff93e18d8308d390a106a
Author: Santtu Lakkala <inz@inz.fi>
Date: Thu, 6 Jul 2023 10:18:36 +0300
Simplify termination
Use longjmp for clean exit, simplifying the logic.
Diffstat:
M | udyfi.c | | | 42 | ++++++++++++------------------------------ |
1 file changed, 12 insertions(+), 30 deletions(-)
diff --git a/udyfi.c b/udyfi.c
@@ -27,6 +27,7 @@
#include <sys/socket.h>
#include <sys/select.h>
#include <signal.h>
+#include <setjmp.h>
#include <poll.h>
#include <fcntl.h>
#include <unistd.h>
@@ -54,7 +55,7 @@
#endif
#include "arg.h"
-static bool running = true;
+static jmp_buf terminate;
char *argv0;
#ifdef USE_LIBTLS
@@ -122,7 +123,7 @@ static char **strsplit(char *s, int *c)
static void sig_handler(int signum)
{
(void)signum;
- running = false;
+ longjmp(terminate, 0);
}
static void sighup_handler(int signum)
@@ -277,10 +278,6 @@ static ssize_t http_get(const char *server,
return -1;
}
-
- if (!running)
- return -1;
-
s = 0;
do {
#ifdef USE_LIBTLS
@@ -290,14 +287,10 @@ static ssize_t http_get(const char *server,
#endif
r = read(sock, buffer + s, bufsize - s - 1);
if (r < 0) {
- if (!running)
- return -1;
#ifdef USE_LIBTLS
if (ctx) {
if (r == TLS_WANT_POLLIN) {
poll(&(struct pollfd){ .fd = sock, .events = POLLIN }, 1, 0);
- if (!running)
- return -1;
continue;
}
@@ -641,7 +634,7 @@ static void daemonize(const char *pidfile) {
int main(int argc, char **argv)
{
const char *username = NULL;
- const char *pidfile = NULL;
+ const char * volatile pidfile = NULL;
const char *iface = NULL;
const char *dropuser = NULL;
const char *domains = NULL;
@@ -657,11 +650,10 @@ int main(int argc, char **argv)
char *prev_ip = ipbuf2;
int background = 0;
int af = AF_UNSPEC;
- int ret = EXIT_SUCCESS;
- FILE *log = stderr;
+ volatile int ret = EXIT_SUCCESS;
+ FILE * volatile log = stderr;
const char *logfile = NULL;
char *arg;
- sigset_t sigset_all;
sigset_t sigset_hup;
sigset_t sigset_dfl;
@@ -676,14 +668,9 @@ int main(int argc, char **argv)
int check_port_set = 0;
bool use_ssl = dyndns_ssl;
bool check_ssl = checkip_ssl;
- struct tls *ctx = NULL;
+ struct tls * volatile ctx = NULL;
#endif
- sigemptyset(&sigset_all);
- sigaddset(&sigset_all, SIGHUP);
- sigaddset(&sigset_all, SIGTERM);
- sigaddset(&sigset_all, SIGINT);
-
sigemptyset(&sigset_hup);
sigaddset(&sigset_hup, SIGHUP);
@@ -895,13 +882,16 @@ cfgtoggle:
fprintf(log, "udyfi started\n");
+ if (setjmp(terminate))
+ goto out;
+
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
sigaction(SIGHUP, &(struct sigaction){ .sa_handler = sighup_handler }, NULL);
sigprocmask(SIG_BLOCK, &sigset_hup, &sigset_dfl);
- while (running) {
+ for (;;) {
time_t now = time(NULL);
if (now >= last_error + error_fallback &&
@@ -976,8 +966,6 @@ cfgtoggle:
ret = EXIT_FAILURE;
goto out;
case UP_NETWORK:
- if (!running)
- goto out;
fprintf(log, "WARNING: "
"Networking error\n");
goto retry;
@@ -994,23 +982,17 @@ cfgtoggle:
ip = prev_ip;
prev_ip = tmp;
}
- } else if (running) {
+ } else {
fprintf(log, "IP check failed.\n");
fflush(log);
}
retry:
- sigprocmask(SIG_BLOCK, &sigset_all, NULL);
- if (!running)
- break;
-
pselect(0, NULL, NULL, NULL, &(struct timespec){
.tv_sec = (last_error + error_fallback < now ?
check_interval + rand() * check_interval_rand / RAND_MAX :
last_error + error_fallback - now + rand() * error_fallback_rand / RAND_MAX)
}, &sigset_dfl);
-
- sigprocmask(SIG_BLOCK, &sigset_hup, NULL);
}
out: