mirror of
https://github.com/curl/curl.git
synced 2026-08-24 23:13:38 +03:00
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 20213fb6e5a010introduced 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 to3fb6e5a010#6529 Closes #22037
This commit is contained in:
parent
2112f185c0
commit
69e8278149
1 changed files with 16 additions and 17 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue