Explicitly initialize sigaction::sa_mask members with sigemptyset(3)

Not doing so before calling sigaction(3) is "undefined" according to
POSIX[1]:

> Applications shall call either sigemptyset() or sigfillset() at least
> once for each object of type sigset_t prior to any other use of that
> object. If such an object is not initialized in this way, but is
> nonetheless supplied as an argument to any of pthread_sigmask(),
> sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(),
> sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or
> sigwaitinfo(), the results are undefined.

The use of designated initializers means that sa_mask members were
still being initialized, but sigset_t is an opaque type and implicit
initialization doesn't necessarily produce the same results as using
sigemptyset(3) (although it typically does on most implementations).

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html
This commit is contained in:
Craig Barnes 2022-02-12 12:04:57 +00:00
parent d34c8007f1
commit 23cf80667a
6 changed files with 16 additions and 6 deletions

View file

@ -1716,7 +1716,9 @@ term_destroy(struct terminal *term)
* course only applies to a 'foot --server' instance, where
* there might be other terminals running.
*/
sigaction(SIGALRM, &(const struct sigaction){.sa_handler = &sig_alarm}, NULL);
struct sigaction action = {.sa_handler = &sig_alarm};
sigemptyset(&action.sa_mask);
sigaction(SIGALRM, &action, NULL);
alarm(60);
while (true) {
@ -1740,7 +1742,8 @@ term_destroy(struct terminal *term)
/* Cancel alarm */
alarm(0);
sigaction(SIGALRM, &(const struct sigaction){.sa_handler = SIG_DFL}, NULL);
action.sa_handler = SIG_DFL;
sigaction(SIGALRM, &action, NULL);
}
ret = EXIT_FAILURE;