# HG changeset patch # User Eric Blake # Date 1214053729 21600 # Node ID 54813304edd2b6fc025da71fc754ba8e9d822c45 # Parent 29502a2dd08a5b3a7ef95a2b6031488893bf7473 Use sigaction module rather than signal(). * modules/c-stack (Depends-on): Add sigaction. * modules/fatal-signal (Depends-on): Likewise. * modules/nanosleep (Depends-on): Likewise. * modules/sigprocmask (Files): Add sig-handler.h. * modules/sigaction (Files): Likewise. * lib/sig-handler.h (get_handler): New file, suggested by Paul Eggert. * lib/c-stack.c (SIGACTION_WORKS): Simplify conditions. (c_stack_action) [!SIGACTION_WORKS]: Use sigaction, not signal. * lib/fatal-signal.c (uninstall_handlers, install_handlers) (init_fatal_signals): Likewise. * lib/nanosleep.c (rpl_nanosleep): Likewise. (siginterrupt): Delete fallback. * lib/sigprocmask.c (handler_t): Delete. (old_handlers): Use sa_handler_t instead. * m4/nanosleep.m4 (gl_PREREQ_NANOSLEEP): Drop check for siginterrupt. Signed-off-by: Eric Blake diff -r 29502a2dd08a -r 54813304edd2 ChangeLog --- a/ChangeLog Sat Jun 21 14:32:55 2008 -0600 +++ b/ChangeLog Sat Jun 21 07:08:49 2008 -0600 @@ -1,5 +1,24 @@ 2008-06-21 Eric Blake + Use sigaction module rather than signal(). + * modules/c-stack (Depends-on): Add sigaction. + * modules/fatal-signal (Depends-on): Likewise. + * modules/nanosleep (Depends-on): Likewise. + * modules/sigprocmask (Files): Add sig-handler.h. + * modules/sigaction (Files): Likewise. + * lib/sig-handler.h (get_handler): New file, suggested by Paul + Eggert. + * lib/c-stack.c (SIGACTION_WORKS): Simplify conditions. + (c_stack_action) [!SIGACTION_WORKS]: Use sigaction, not signal. + * lib/fatal-signal.c (uninstall_handlers, install_handlers) + (init_fatal_signals): Likewise. + * lib/nanosleep.c (rpl_nanosleep): Likewise. + (siginterrupt): Delete fallback. + * lib/sigprocmask.c (handler_t, old_handlers): Use sa_handler_t + instead. + * m4/nanosleep.m4 (gl_PREREQ_NANOSLEEP): Drop check for + siginterrupt. + New module sigaction, for mingw. * modules/sigaction: New module... * modules/sigaction-tests: ...and its test. diff -r 29502a2dd08a -r 54813304edd2 lib/c-stack.c --- a/lib/c-stack.c Sat Jun 21 14:32:55 2008 -0600 +++ b/lib/c-stack.c Sat Jun 21 07:08:49 2008 -0600 @@ -71,8 +71,7 @@ #include "c-stack.h" #include "exitfail.h" -#if (HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined SA_NODEFER \ - && defined SA_ONSTACK && defined SA_RESETHAND && defined SA_SIGINFO) +#if defined SA_ONSTACK && defined SA_SIGINFO # define SIGACTION_WORKS 1 #else # define SIGACTION_WORKS 0 @@ -168,7 +167,7 @@ char const *faulting_address = info->si_addr; size_t s = faulting_address - stack_base; size_t page_size = sysconf (_SC_PAGESIZE); - if (find_stack_direction (0) < 0) + if (find_stack_direction (NULL) < 0) s += page_size; if (s < stack_size + page_size) signo = 0; @@ -213,10 +212,11 @@ { int r; stack_t st; + struct sigaction act; st.ss_flags = 0; st.ss_sp = alternate_signal_stack.buffer; st.ss_size = sizeof alternate_signal_stack.buffer; - r = sigaltstack (&st, 0); + r = sigaltstack (&st, NULL); if (r != 0) return r; @@ -224,23 +224,20 @@ program_error_message = _("program error"); stack_overflow_message = _("stack overflow"); - { -# if SIGACTION_WORKS - struct sigaction act; - sigemptyset (&act.sa_mask); + sigemptyset (&act.sa_mask); - /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but - this is not true on Solaris 8 at least. It doesn't hurt to use - SA_NODEFER here, so leave it in. */ - act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; +# if SIGACTION_WORKS + /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but + this is not true on Solaris 8 at least. It doesn't hurt to use + SA_NODEFER here, so leave it in. */ + act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; + act.sa_sigaction = segv_handler; +# else + act.sa_flags = SA_NODEFER | SA_RESETHAND; + act.sa_handler = die; +# endif - act.sa_sigaction = segv_handler; - - return sigaction (SIGSEGV, &act, 0); -# else - return signal (SIGSEGV, die) == SIG_ERR ? -1 : 0; -# endif - } + return sigaction (SIGSEGV, &act, NULL); } #else /* ! (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) */ diff -r 29502a2dd08a -r 54813304edd2 lib/fatal-signal.c --- a/lib/fatal-signal.c Sat Jun 21 14:32:55 2008 -0600 +++ b/lib/fatal-signal.c Sat Jun 21 07:08:49 2008 -0600 @@ -26,11 +26,11 @@ #include #include +#include "sig-handler.h" #include "xalloc.h" #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) - /* ========================================================================= */ @@ -88,7 +88,6 @@ static bool fatal_signals_initialized = false; if (!fatal_signals_initialized) { -#if HAVE_SIGACTION size_t i; for (i = 0; i < num_fatal_signals; i++) @@ -96,14 +95,9 @@ struct sigaction action; if (sigaction (fatal_signals[i], NULL, &action) >= 0 - /* POSIX says that SIG_IGN can only occur when action.sa_flags - does not contain SA_SIGINFO. But in Linux 2.4, for example, - SA_SIGINFO can actually be set and is ignored when sa_handler - is SIG_IGN. So don't bother testing for SA_SIGINFO. */ - && action.sa_handler == SIG_IGN) + && get_handler (&action) == SIG_IGN) fatal_signals[i] = -1; } -#endif fatal_signals_initialized = true; } @@ -136,10 +130,14 @@ uninstall_handlers () { size_t i; + struct sigaction action; + action.sa_handler = SIG_DFL; + action.sa_flags = 0; + sigemptyset (&action.sa_mask); for (i = 0; i < num_fatal_signals; i++) if (fatal_signals[i] >= 0) - signal (fatal_signals[i], SIG_DFL); + sigaction (fatal_signals[i], &action, NULL); } @@ -162,9 +160,9 @@ } /* Now execute the signal's default action. - If signal() blocks the signal being delivered for the duration of the - signal handler's execution, the re-raised signal is delivered when this - handler returns; otherwise it is delivered already during raise(). */ + If any cleanup action blocks the signal that triggered the cleanup, the + re-raised signal is delivered when this handler returns; otherwise it + is delivered already during raise(). */ uninstall_handlers (); raise (sig); } @@ -175,10 +173,16 @@ install_handlers () { size_t i; + struct sigaction action; + action.sa_handler = &fatal_signal_handler; + /* One-shot handling - if we fault while handling a fault, the + cleanup actions are intentionally cut short. */ + action.sa_flags = SA_NODEFER | SA_RESETHAND; + sigemptyset (&action.sa_mask); for (i = 0; i < num_fatal_signals; i++) if (fatal_signals[i] >= 0) - signal (fatal_signals[i], &fatal_signal_handler); + sigaction (fatal_signals[i], &action, NULL); } diff -r 29502a2dd08a -r 54813304edd2 lib/nanosleep.c --- a/lib/nanosleep.c Sat Jun 21 14:32:55 2008 -0600 +++ b/lib/nanosleep.c Sat Jun 21 07:08:49 2008 -0600 @@ -22,6 +22,7 @@ #include +#include "sig-handler.h" #include "timespec.h" #include @@ -102,10 +103,6 @@ # define SIGCONT SIGTERM # endif -# if ! HAVE_SIGINTERRUPT -# define siginterrupt(sig, flag) /* empty */ -# endif - static sig_atomic_t volatile suspended; /* Handle SIGCONT. */ @@ -150,22 +147,14 @@ /* set up sig handler */ if (! initialized) { -# ifdef SA_NOCLDSTOP struct sigaction oldact, newact; newact.sa_handler = sighandler; sigemptyset (&newact.sa_mask); newact.sa_flags = 0; sigaction (SIGCONT, NULL, &oldact); - if (oldact.sa_handler != SIG_IGN) + if (get_handler (&oldact) != SIG_IGN) sigaction (SIGCONT, &newact, NULL); -# else - if (signal (SIGCONT, SIG_IGN) != SIG_IGN) - { - signal (SIGCONT, sighandler); - siginterrupt (SIGCONT, 1); - } -# endif initialized = true; } diff -r 29502a2dd08a -r 54813304edd2 lib/sig-handler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/sig-handler.h Sat Jun 21 07:08:49 2008 -0600 @@ -0,0 +1,44 @@ +/* Convenience declarations when working with . + + Copyright (C) 2008 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef _GL_SIG_HANDLER_H +#define _GL_SIG_HANDLER_H + +#include + +/* Convenience type when working with signal handlers. */ +typedef void (*sa_handler_t) (int); + +/* Return the handler of a signal, as a sa_handler_t value regardless + of its true type. The resulting function can be compared to + special values like SIG_IGN but it is not portable to call it. */ +static inline sa_handler_t +get_handler (struct sigaction const *a) +{ +#ifdef SA_SIGINFO + /* POSIX says that special values like SIG_IGN can only occur when + action.sa_flags does not contain SA_SIGINFO. But in Linux 2.4, + for example, sa_sigaction and sa_handler are aliases and a signal + is ignored if sa_sigaction (after casting) equals SIG_IGN. So + use (and cast) sa_sigaction in that case. */ + if (a->sa_flags & SA_SIGINFO) + return (sa_handler_t) a->sa_sigaction; +#endif + return a->sa_handler; +} + +#endif /* _GL_SIG_HANDLER_H */ diff -r 29502a2dd08a -r 54813304edd2 lib/sigprocmask.c --- a/lib/sigprocmask.c Sat Jun 21 14:32:55 2008 -0600 +++ b/lib/sigprocmask.c Sat Jun 21 07:08:49 2008 -0600 @@ -24,6 +24,8 @@ #include #include +#include "sig-handler.h" + /* We assume that a platform without POSIX signal blocking functions also does not have the POSIX sigaction() function, only the signal() function. We also assume signal() has SysV semantics, @@ -43,9 +45,6 @@ # define SIGSTOP (-1) #endif -/* A signal handler. */ -typedef void (*handler_t) (int signal); - int sigismember (const sigset_t *set, int sig) { @@ -134,7 +133,7 @@ /* The previous signal handlers. Only the array elements corresponding to blocked signals are relevant. */ -static volatile handler_t old_handlers[NSIG]; +static volatile sa_handler_t old_handlers[NSIG]; int sigprocmask (int operation, const sigset_t *set, sigset_t *old_set) @@ -208,8 +207,8 @@ /* Install the handler FUNC for signal SIG, and return the previous handler. */ -handler_t -rpl_signal (int sig, handler_t handler) +sa_handler_t +rpl_signal (int sig, sa_handler_t handler) { /* We must provide a wrapper, so that a user can query what handler they installed even if that signal is currently blocked. */ @@ -227,7 +226,7 @@ stale information if it calls signal(B). Oh well - signal handlers really shouldn't try to manipulate the installed handlers of unrelated signals. */ - handler_t result = old_handlers[sig]; + sa_handler_t result = old_handlers[sig]; old_handlers[sig] = handler; return result; } diff -r 29502a2dd08a -r 54813304edd2 m4/nanosleep.m4 --- a/m4/nanosleep.m4 Sat Jun 21 14:32:55 2008 -0600 +++ b/m4/nanosleep.m4 Sat Jun 21 07:08:49 2008 -0600 @@ -1,12 +1,12 @@ -#serial 23 +#serial 24 dnl From Jim Meyering. dnl Check for the nanosleep function. dnl If not found, use the supplied replacement. dnl -# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free -# Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -111,6 +111,5 @@ # Prerequisites of lib/nanosleep.c. AC_DEFUN([gl_PREREQ_NANOSLEEP], [ - AC_CHECK_FUNCS_ONCE(siginterrupt) AC_CHECK_HEADERS_ONCE(sys/select.h) ]) diff -r 29502a2dd08a -r 54813304edd2 modules/c-stack --- a/modules/c-stack Sat Jun 21 14:32:55 2008 -0600 +++ b/modules/c-stack Sat Jun 21 07:08:49 2008 -0600 @@ -11,6 +11,7 @@ exitfail unistd raise +sigaction configure.ac: gl_C_STACK diff -r 29502a2dd08a -r 54813304edd2 modules/fatal-signal --- a/modules/fatal-signal Sat Jun 21 14:32:55 2008 -0600 +++ b/modules/fatal-signal Sat Jun 21 07:08:49 2008 -0600 @@ -11,6 +11,7 @@ xalloc stdbool unistd +sigaction sigprocmask raise diff -r 29502a2dd08a -r 54813304edd2 modules/nanosleep --- a/modules/nanosleep Sat Jun 21 14:32:55 2008 -0600 +++ b/modules/nanosleep Sat Jun 21 07:08:49 2008 -0600 @@ -9,6 +9,7 @@ clock-time extensions gettime +sigaction stdbool sys_select sys_time diff -r 29502a2dd08a -r 54813304edd2 modules/sigaction --- a/modules/sigaction Sat Jun 21 14:32:55 2008 -0600 +++ b/modules/sigaction Sat Jun 21 07:08:49 2008 -0600 @@ -3,6 +3,7 @@ Files: lib/sigaction.c +lib/sig-handler.h m4/sigaction.m4 Depends-on: diff -r 29502a2dd08a -r 54813304edd2 modules/sigprocmask --- a/modules/sigprocmask Sat Jun 21 14:32:55 2008 -0600 +++ b/modules/sigprocmask Sat Jun 21 07:08:49 2008 -0600 @@ -3,6 +3,7 @@ Files: lib/sigprocmask.c +lib/sig-handler.h m4/signalblocking.m4 Depends-on: