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: