From: Viktor Szakats Date: Tue, 16 Jun 2026 01:07:58 +0000 (+0200) Subject: servers: fix to reverse `SA_RESTART` option for `sigaction()` on modern codepath X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fcurl.git servers: fix to reverse `SA_RESTART` option for `sigaction()` on modern codepath Historically servers used the deprecated `siginterrupt()` function to configure restart behavior on specific signals. It accepts a flag, where 1 means to remove the `SA_RESTART` option, and 0 means to enable it. In year 2021 3fb6e5a01001b8c7dfdc33a89041178aac381a27 introduced the modern alternative to the codebase, replacing `siginterrupt()` with `sigaction()`. After this patch, supporting, modern, systems reacted on the same flag, but, by accident, set the `SA_RESTART` bit when flag is 1, and did not set it when 0. This reversed the previous behavior, and the one still used on the `siginterrupt()` legacy codepath. Fix it by revesring the `SA_RESTART` logic for the `sigaction()` codepath, syncing it with the pre-existing behavior. I find it odd this did not cause any perceivable issue for 5 years, even though it's the active one in most Unix envs. Spotted by GitHub Code Quality, though suggesting to fix `siginterrupt()` calls. But looking into the history, those were correct all along. Refs: https://pubs.opengroup.org/onlinepubs/9699919799/functions/siginterrupt.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html https://www.man7.org/linux/man-pages/man3/siginterrupt.3.html https://www.man7.org/linux/man-pages/man2/sigaction.2.html Follow-up to 3fb6e5a01001b8c7dfdc33a89041178aac381a27 #6529 Closes #22037 --- diff --git a/tests/server/util.c b/tests/server/util.c index 805f615f4c..2bb5b3f96d 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -555,8 +555,7 @@ static DWORD WINAPI main_window_loop(void *lpParameter) } #endif -static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, - bool restartable) +static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, int norestart) { #if defined(HAVE_SIGACTION) && defined(SA_RESTART) struct sigaction sa, oldsa; @@ -565,7 +564,7 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, signum); - sa.sa_flags = restartable ? SA_RESTART : 0; + sa.sa_flags = norestart ? 0 : SA_RESTART; if(sigaction(signum, &sa, &oldsa)) return SIG_ERR; @@ -576,9 +575,9 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, #ifdef HAVE_SIGINTERRUPT if(oldhdlr != SIG_ERR) - siginterrupt(signum, (int)restartable); + siginterrupt(signum, norestart); #else - (void)restartable; + (void)norestart; #endif return oldhdlr; @@ -597,14 +596,14 @@ void install_signal_handlers(bool keep_sigalrm) #endif #ifdef SIGHUP /* ignore SIGHUP signal */ - old_sighup_handler = set_signal(SIGHUP, SIG_IGN, FALSE); + old_sighup_handler = set_signal(SIGHUP, SIG_IGN, 0); if(old_sighup_handler == SIG_ERR) logmsg("cannot install SIGHUP handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); #endif #ifdef SIGPIPE /* ignore SIGPIPE signal */ - old_sigpipe_handler = set_signal(SIGPIPE, SIG_IGN, FALSE); + old_sigpipe_handler = set_signal(SIGPIPE, SIG_IGN, 0); if(old_sigpipe_handler == SIG_ERR) logmsg("cannot install SIGPIPE handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); @@ -612,7 +611,7 @@ void install_signal_handlers(bool keep_sigalrm) #ifdef SIGALRM if(!keep_sigalrm) { /* ignore SIGALRM signal */ - old_sigalrm_handler = set_signal(SIGALRM, SIG_IGN, FALSE); + old_sigalrm_handler = set_signal(SIGALRM, SIG_IGN, 0); if(old_sigalrm_handler == SIG_ERR) logmsg("cannot install SIGALRM handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); @@ -622,21 +621,21 @@ void install_signal_handlers(bool keep_sigalrm) #endif #ifdef SIGINT /* handle SIGINT signal with our exit_signal_handler */ - old_sigint_handler = set_signal(SIGINT, exit_signal_handler, TRUE); + old_sigint_handler = set_signal(SIGINT, exit_signal_handler, 1); if(old_sigint_handler == SIG_ERR) logmsg("cannot install SIGINT handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); #endif #ifdef SIGTERM /* handle SIGTERM signal with our exit_signal_handler */ - old_sigterm_handler = set_signal(SIGTERM, exit_signal_handler, TRUE); + old_sigterm_handler = set_signal(SIGTERM, exit_signal_handler, 1); if(old_sigterm_handler == SIG_ERR) logmsg("cannot install SIGTERM handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); #endif #if defined(SIGBREAK) && defined(_WIN32) /* handle SIGBREAK signal with our exit_signal_handler */ - old_sigbreak_handler = set_signal(SIGBREAK, exit_signal_handler, TRUE); + old_sigbreak_handler = set_signal(SIGBREAK, exit_signal_handler, 1); if(old_sigbreak_handler == SIG_ERR) logmsg("cannot install SIGBREAK handler: (%d) %s", errno, curlx_strerror(errno, errbuf, sizeof(errbuf))); @@ -658,31 +657,31 @@ void restore_signal_handlers(bool keep_sigalrm) { #ifdef SIGHUP if(old_sighup_handler != SIG_ERR) - (void)set_signal(SIGHUP, old_sighup_handler, FALSE); + (void)set_signal(SIGHUP, old_sighup_handler, 0); #endif #ifdef SIGPIPE if(old_sigpipe_handler != SIG_ERR) - (void)set_signal(SIGPIPE, old_sigpipe_handler, FALSE); + (void)set_signal(SIGPIPE, old_sigpipe_handler, 0); #endif #ifdef SIGALRM if(!keep_sigalrm) { if(old_sigalrm_handler != SIG_ERR) - (void)set_signal(SIGALRM, old_sigalrm_handler, FALSE); + (void)set_signal(SIGALRM, old_sigalrm_handler, 0); } #else (void)keep_sigalrm; #endif #ifdef SIGINT if(old_sigint_handler != SIG_ERR) - (void)set_signal(SIGINT, old_sigint_handler, FALSE); + (void)set_signal(SIGINT, old_sigint_handler, 0); #endif #ifdef SIGTERM if(old_sigterm_handler != SIG_ERR) - (void)set_signal(SIGTERM, old_sigterm_handler, FALSE); + (void)set_signal(SIGTERM, old_sigterm_handler, 0); #endif #if defined(SIGBREAK) && defined(_WIN32) if(old_sigbreak_handler != SIG_ERR) - (void)set_signal(SIGBREAK, old_sigbreak_handler, FALSE); + (void)set_signal(SIGBREAK, old_sigbreak_handler, 0); #endif #ifdef _WIN32 (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE);