From d6598752ab09b188178f1891c47efdf97fbc0bac Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 6 Apr 2009 17:45:44 +0200 Subject: [PATCH] signal: Switch from signal() to sigaction. Use of signal() should be avoided because the behavior of signal() varies across Unix versions, and has also varied historically across different versions of Linux. This patch rewrites para_install_sighandler so that it calls sigaction() instead of signal(). The implementation is taken from good old APUE. There are a couple of other users of signal() in the paraslash code. Most of which are OK because they use signal() only to ignore/reset a signal which happens to be the only portable use of signal(). All other users of signal() have to be converted in subsequent patches. --- signal.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/signal.c b/signal.c index acc87802..9a1dcfb0 100644 --- a/signal.c +++ b/signal.c @@ -117,20 +117,34 @@ void para_reap_children(void) } /** - * Wrapper around signal(2). + * Install the generic signal handler for the given signal number. * * \param sig The number of the signal to catch. * - * This installs the generic signal handler for the given signal. - * * \return This function returns 1 on success and \p -E_SIGNAL_SIG_ERR on errors. * - * \sa signal(2). + * \sa signal(2), sigaction(2). */ int para_install_sighandler(int sig) { + struct sigaction act; + PARA_DEBUG_LOG("catching signal %d\n", sig); - return signal(sig, &generic_signal_handler) == SIG_ERR? -E_SIGNAL_SIG_ERR : 1; + act.sa_handler = &generic_signal_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (sig == SIGALRM) { + #ifdef SA_INTERRUPT /* SunOS */ + act.sa_flags |= SA_INTERRUPT; + #endif + } else { + #ifdef SA_RESTART /* BSD */ + act.sa_flags |= SA_RESTART; + #endif + } + if (sigaction(sig, &act, NULL) < 0) + return -E_SIGNAL_SIG_ERR; + return 1; } /** -- 2.39.5