Mercurial > hg > octave-nkf > gnulib-hg
changeset 10230:54813304edd2
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 <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Sat, 21 Jun 2008 07:08:49 -0600 |
parents | 29502a2dd08a |
children | 32f7d74b65e8 |
files | ChangeLog lib/c-stack.c lib/fatal-signal.c lib/nanosleep.c lib/sig-handler.h lib/sigprocmask.c m4/nanosleep.m4 modules/c-stack modules/fatal-signal modules/nanosleep modules/sigaction modules/sigprocmask |
diffstat | 12 files changed, 112 insertions(+), 56 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2008-06-21 Eric Blake <ebb9@byu.net> + 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.
--- a/lib/c-stack.c +++ b/lib/c-stack.c @@ -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) */
--- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -26,11 +26,11 @@ #include <signal.h> #include <unistd.h> +#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); }
--- a/lib/nanosleep.c +++ b/lib/nanosleep.c @@ -22,6 +22,7 @@ #include <time.h> +#include "sig-handler.h" #include "timespec.h" #include <stdbool.h> @@ -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; }
new file mode 100644 --- /dev/null +++ b/lib/sig-handler.h @@ -0,0 +1,44 @@ +/* Convenience declarations when working with <signal.h>. + + 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 <http://www.gnu.org/licenses/>. */ + +#ifndef _GL_SIG_HANDLER_H +#define _GL_SIG_HANDLER_H + +#include <signal.h> + +/* 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 */
--- a/lib/sigprocmask.c +++ b/lib/sigprocmask.c @@ -24,6 +24,8 @@ #include <stdint.h> #include <stdlib.h> +#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; }
--- a/m4/nanosleep.m4 +++ b/m4/nanosleep.m4 @@ -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) ])
--- a/modules/c-stack +++ b/modules/c-stack @@ -11,6 +11,7 @@ exitfail unistd raise +sigaction configure.ac: gl_C_STACK
--- a/modules/fatal-signal +++ b/modules/fatal-signal @@ -11,6 +11,7 @@ xalloc stdbool unistd +sigaction sigprocmask raise
--- a/modules/nanosleep +++ b/modules/nanosleep @@ -9,6 +9,7 @@ clock-time extensions gettime +sigaction stdbool sys_select sys_time