mirror of https://github.com/GOSTSec/sgminer
Con Kolivas
14 years ago
13 changed files with 1181 additions and 2 deletions
@ -0,0 +1,44 @@ |
|||||||
|
/* Convenience declarations when working with <signal.h>.
|
||||||
|
|
||||||
|
Copyright (C) 2008-2011 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 */ |
@ -0,0 +1,204 @@ |
|||||||
|
/* POSIX compatible signal blocking.
|
||||||
|
Copyright (C) 2008-2011 Free Software Foundation, Inc. |
||||||
|
Written by Eric Blake <ebb9@byu.net>, 2008. |
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
#include <config.h> |
||||||
|
|
||||||
|
/* Specification. */ |
||||||
|
#include <signal.h> |
||||||
|
|
||||||
|
#include <errno.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
/* This implementation of sigaction is tailored to Woe32 behavior:
|
||||||
|
signal() has SysV semantics (ie. the handler is uninstalled before |
||||||
|
it is invoked). This is an inherent data race if an asynchronous |
||||||
|
signal is sent twice in a row before we can reinstall our handler, |
||||||
|
but there's nothing we can do about it. Meanwhile, sigprocmask() |
||||||
|
is not present, and while we can use the gnulib replacement to |
||||||
|
provide critical sections, it too suffers from potential data races |
||||||
|
in the face of an ill-timed asynchronous signal. And we compound |
||||||
|
the situation by reading static storage in a signal handler, which |
||||||
|
POSIX warns is not generically async-signal-safe. Oh well. |
||||||
|
|
||||||
|
Additionally: |
||||||
|
- We don't implement SA_NOCLDSTOP or SA_NOCLDWAIT, because SIGCHLD |
||||||
|
is not defined. |
||||||
|
- We don't implement SA_ONSTACK, because sigaltstack() is not present. |
||||||
|
- We ignore SA_RESTART, because blocking Win32 calls are not interrupted |
||||||
|
anyway when an asynchronous signal occurs, and the MSVCRT runtime |
||||||
|
never sets errno to EINTR. |
||||||
|
- We don't implement SA_SIGINFO because it is impossible to do so |
||||||
|
portably. |
||||||
|
|
||||||
|
POSIX states that an application should not mix signal() and |
||||||
|
sigaction(). We support the use of signal() within the gnulib |
||||||
|
sigprocmask() substitute, but all other application code linked |
||||||
|
with this module should stick with only sigaction(). */ |
||||||
|
|
||||||
|
/* Check some of our assumptions. */ |
||||||
|
#if defined SIGCHLD || defined HAVE_SIGALTSTACK || defined HAVE_SIGINTERRUPT |
||||||
|
# error "Revisit the assumptions made in the sigaction module" |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Out-of-range substitutes make a good fallback for uncatchable
|
||||||
|
signals. */ |
||||||
|
#ifndef SIGKILL |
||||||
|
# define SIGKILL (-1) |
||||||
|
#endif |
||||||
|
#ifndef SIGSTOP |
||||||
|
# define SIGSTOP (-1) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
|
||||||
|
for the signal SIGABRT. Only one signal handler is stored for both |
||||||
|
SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */ |
||||||
|
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
||||||
|
# undef SIGABRT_COMPAT |
||||||
|
# define SIGABRT_COMPAT 6 |
||||||
|
#endif |
||||||
|
|
||||||
|
/* A signal handler. */ |
||||||
|
typedef void (*handler_t) (int signal); |
||||||
|
|
||||||
|
/* Set of current actions. If sa_handler for an entry is NULL, then
|
||||||
|
that signal is not currently handled by the sigaction handler. */ |
||||||
|
static struct sigaction volatile action_array[NSIG] /* = 0 */; |
||||||
|
|
||||||
|
/* Signal handler that is installed for signals. */ |
||||||
|
static void |
||||||
|
sigaction_handler (int sig) |
||||||
|
{ |
||||||
|
handler_t handler; |
||||||
|
sigset_t mask; |
||||||
|
sigset_t oldmask; |
||||||
|
int saved_errno = errno; |
||||||
|
if (sig < 0 || NSIG <= sig || !action_array[sig].sa_handler) |
||||||
|
{ |
||||||
|
/* Unexpected situation; be careful to avoid recursive abort. */ |
||||||
|
if (sig == SIGABRT) |
||||||
|
signal (SIGABRT, SIG_DFL); |
||||||
|
abort (); |
||||||
|
} |
||||||
|
|
||||||
|
/* Reinstall the signal handler when required; otherwise update the
|
||||||
|
bookkeeping so that the user's handler may call sigaction and get |
||||||
|
accurate results. We know the signal isn't currently blocked, or |
||||||
|
we wouldn't be in its handler, therefore we know that we are not |
||||||
|
interrupting a sigaction() call. There is a race where any |
||||||
|
asynchronous instance of the same signal occurring before we |
||||||
|
reinstall the handler will trigger the default handler; oh |
||||||
|
well. */ |
||||||
|
handler = action_array[sig].sa_handler; |
||||||
|
if ((action_array[sig].sa_flags & SA_RESETHAND) == 0) |
||||||
|
signal (sig, sigaction_handler); |
||||||
|
else |
||||||
|
action_array[sig].sa_handler = NULL; |
||||||
|
|
||||||
|
/* Block appropriate signals. */ |
||||||
|
mask = action_array[sig].sa_mask; |
||||||
|
if ((action_array[sig].sa_flags & SA_NODEFER) == 0) |
||||||
|
sigaddset (&mask, sig); |
||||||
|
sigprocmask (SIG_BLOCK, &mask, &oldmask); |
||||||
|
|
||||||
|
/* Invoke the user's handler, then restore prior mask. */ |
||||||
|
errno = saved_errno; |
||||||
|
handler (sig); |
||||||
|
saved_errno = errno; |
||||||
|
sigprocmask (SIG_SETMASK, &oldmask, NULL); |
||||||
|
errno = saved_errno; |
||||||
|
} |
||||||
|
|
||||||
|
/* Change and/or query the action that will be taken on delivery of
|
||||||
|
signal SIG. If not NULL, ACT describes the new behavior. If not |
||||||
|
NULL, OACT is set to the prior behavior. Return 0 on success, or |
||||||
|
set errno and return -1 on failure. */ |
||||||
|
int |
||||||
|
sigaction (int sig, const struct sigaction *restrict act, |
||||||
|
struct sigaction *restrict oact) |
||||||
|
{ |
||||||
|
sigset_t mask; |
||||||
|
sigset_t oldmask; |
||||||
|
int saved_errno; |
||||||
|
|
||||||
|
if (sig < 0 || NSIG <= sig || sig == SIGKILL || sig == SIGSTOP |
||||||
|
|| (act && act->sa_handler == SIG_ERR)) |
||||||
|
{ |
||||||
|
errno = EINVAL; |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
if (sig == SIGABRT_COMPAT) |
||||||
|
sig = SIGABRT; |
||||||
|
#endif |
||||||
|
|
||||||
|
/* POSIX requires sigaction() to be async-signal-safe. In other
|
||||||
|
words, if an asynchronous signal can occur while we are anywhere |
||||||
|
inside this function, the user's handler could then call |
||||||
|
sigaction() recursively and expect consistent results. We meet |
||||||
|
this rule by using sigprocmask to block all signals before |
||||||
|
modifying any data structure that could be read from a signal |
||||||
|
handler; this works since we know that the gnulib sigprocmask |
||||||
|
replacement does not try to use sigaction() from its handler. */ |
||||||
|
if (!act && !oact) |
||||||
|
return 0; |
||||||
|
sigfillset (&mask); |
||||||
|
sigprocmask (SIG_BLOCK, &mask, &oldmask); |
||||||
|
if (oact) |
||||||
|
{ |
||||||
|
if (action_array[sig].sa_handler) |
||||||
|
*oact = action_array[sig]; |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Safe to change the handler at will here, since all
|
||||||
|
signals are currently blocked. */ |
||||||
|
oact->sa_handler = signal (sig, SIG_DFL); |
||||||
|
if (oact->sa_handler == SIG_ERR) |
||||||
|
goto failure; |
||||||
|
signal (sig, oact->sa_handler); |
||||||
|
oact->sa_flags = SA_RESETHAND | SA_NODEFER; |
||||||
|
sigemptyset (&oact->sa_mask); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (act) |
||||||
|
{ |
||||||
|
/* Safe to install the handler before updating action_array,
|
||||||
|
since all signals are currently blocked. */ |
||||||
|
if (act->sa_handler == SIG_DFL || act->sa_handler == SIG_IGN) |
||||||
|
{ |
||||||
|
if (signal (sig, act->sa_handler) == SIG_ERR) |
||||||
|
goto failure; |
||||||
|
action_array[sig].sa_handler = NULL; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (signal (sig, sigaction_handler) == SIG_ERR) |
||||||
|
goto failure; |
||||||
|
action_array[sig] = *act; |
||||||
|
} |
||||||
|
} |
||||||
|
sigprocmask (SIG_SETMASK, &oldmask, NULL); |
||||||
|
return 0; |
||||||
|
|
||||||
|
failure: |
||||||
|
saved_errno = errno; |
||||||
|
sigprocmask (SIG_SETMASK, &oldmask, NULL); |
||||||
|
errno = saved_errno; |
||||||
|
return -1; |
||||||
|
} |
@ -0,0 +1,376 @@ |
|||||||
|
/* A GNU-like <signal.h>.
|
||||||
|
|
||||||
|
Copyright (C) 2006-2011 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/>. */
|
||||||
|
|
||||||
|
#if __GNUC__ >= 3 |
||||||
|
@PRAGMA_SYSTEM_HEADER@ |
||||||
|
#endif |
||||||
|
@PRAGMA_COLUMNS@ |
||||||
|
|
||||||
|
#if defined __need_sig_atomic_t || defined __need_sigset_t |
||||||
|
/* Special invocation convention inside glibc header files. */ |
||||||
|
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SIGNAL_H@ |
||||||
|
|
||||||
|
#else |
||||||
|
/* Normal invocation convention. */ |
||||||
|
|
||||||
|
#ifndef _@GUARD_PREFIX@_SIGNAL_H |
||||||
|
|
||||||
|
/* The include_next requires a split double-inclusion guard. */ |
||||||
|
#@INCLUDE_NEXT@ @NEXT_SIGNAL_H@ |
||||||
|
|
||||||
|
#ifndef _@GUARD_PREFIX@_SIGNAL_H |
||||||
|
#define _@GUARD_PREFIX@_SIGNAL_H |
||||||
|
|
||||||
|
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ |
||||||
|
|
||||||
|
/* The definition of _GL_ARG_NONNULL is copied here. */ |
||||||
|
|
||||||
|
/* The definition of _GL_WARN_ON_USE is copied here. */ |
||||||
|
|
||||||
|
/* Define pid_t, uid_t.
|
||||||
|
Also, mingw defines sigset_t not in <signal.h>, but in <sys/types.h>. */ |
||||||
|
#include <sys/types.h> |
||||||
|
|
||||||
|
/* On AIX, sig_atomic_t already includes volatile. C99 requires that
|
||||||
|
'volatile sig_atomic_t' ignore the extra modifier, but C89 did not. |
||||||
|
Hence, redefine this to a non-volatile type as needed. */ |
||||||
|
#if ! @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ |
||||||
|
# if !GNULIB_defined_sig_atomic_t |
||||||
|
typedef int rpl_sig_atomic_t; |
||||||
|
# undef sig_atomic_t |
||||||
|
# define sig_atomic_t rpl_sig_atomic_t |
||||||
|
# define GNULIB_defined_sig_atomic_t 1 |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* A set or mask of signals. */ |
||||||
|
#if !@HAVE_SIGSET_T@ |
||||||
|
# if !GNULIB_defined_sigset_t |
||||||
|
typedef unsigned int sigset_t; |
||||||
|
# define GNULIB_defined_sigset_t 1 |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Define sighandler_t, the type of signal handlers. A GNU extension. */ |
||||||
|
#if !@HAVE_SIGHANDLER_T@ |
||||||
|
# ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
# endif |
||||||
|
# if !GNULIB_defined_sighandler_t |
||||||
|
typedef void (*sighandler_t) (int); |
||||||
|
# define GNULIB_defined_sighandler_t 1 |
||||||
|
# endif |
||||||
|
# ifdef __cplusplus |
||||||
|
} |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#if @GNULIB_SIGNAL_H_SIGPIPE@ |
||||||
|
# ifndef SIGPIPE |
||||||
|
/* Define SIGPIPE to a value that does not overlap with other signals. */ |
||||||
|
# define SIGPIPE 13 |
||||||
|
# define GNULIB_defined_SIGPIPE 1 |
||||||
|
/* To actually use SIGPIPE, you also need the gnulib modules 'sigprocmask',
|
||||||
|
'write', 'stdio'. */ |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
/* Maximum signal number + 1. */ |
||||||
|
#ifndef NSIG |
||||||
|
# if defined __TANDEM |
||||||
|
# define NSIG 32 |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#if @GNULIB_SIGPROCMASK@ |
||||||
|
# if !@HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
|
||||||
|
/* Maximum signal number + 1. */ |
||||||
|
# ifndef NSIG |
||||||
|
# define NSIG 32 |
||||||
|
# endif |
||||||
|
|
||||||
|
/* This code supports only 32 signals. */ |
||||||
|
# if !GNULIB_defined_verify_NSIG_constraint |
||||||
|
typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1]; |
||||||
|
# define GNULIB_defined_verify_NSIG_constraint 1 |
||||||
|
# endif |
||||||
|
|
||||||
|
# endif |
||||||
|
|
||||||
|
/* Test whether a given signal is contained in a signal set. */ |
||||||
|
# if @HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
/* This function is defined as a macro on MacOS X. */ |
||||||
|
# if defined __cplusplus && defined GNULIB_NAMESPACE |
||||||
|
# undef sigismember |
||||||
|
# endif |
||||||
|
# else |
||||||
|
_GL_FUNCDECL_SYS (sigismember, int, (const sigset_t *set, int sig) |
||||||
|
_GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigismember, int, (const sigset_t *set, int sig)); |
||||||
|
_GL_CXXALIASWARN (sigismember); |
||||||
|
|
||||||
|
/* Initialize a signal set to the empty set. */ |
||||||
|
# if @HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
/* This function is defined as a macro on MacOS X. */ |
||||||
|
# if defined __cplusplus && defined GNULIB_NAMESPACE |
||||||
|
# undef sigemptyset |
||||||
|
# endif |
||||||
|
# else |
||||||
|
_GL_FUNCDECL_SYS (sigemptyset, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigemptyset, int, (sigset_t *set)); |
||||||
|
_GL_CXXALIASWARN (sigemptyset); |
||||||
|
|
||||||
|
/* Add a signal to a signal set. */ |
||||||
|
# if @HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
/* This function is defined as a macro on MacOS X. */ |
||||||
|
# if defined __cplusplus && defined GNULIB_NAMESPACE |
||||||
|
# undef sigaddset |
||||||
|
# endif |
||||||
|
# else |
||||||
|
_GL_FUNCDECL_SYS (sigaddset, int, (sigset_t *set, int sig) |
||||||
|
_GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigaddset, int, (sigset_t *set, int sig)); |
||||||
|
_GL_CXXALIASWARN (sigaddset); |
||||||
|
|
||||||
|
/* Remove a signal from a signal set. */ |
||||||
|
# if @HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
/* This function is defined as a macro on MacOS X. */ |
||||||
|
# if defined __cplusplus && defined GNULIB_NAMESPACE |
||||||
|
# undef sigdelset |
||||||
|
# endif |
||||||
|
# else |
||||||
|
_GL_FUNCDECL_SYS (sigdelset, int, (sigset_t *set, int sig) |
||||||
|
_GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigdelset, int, (sigset_t *set, int sig)); |
||||||
|
_GL_CXXALIASWARN (sigdelset); |
||||||
|
|
||||||
|
/* Fill a signal set with all possible signals. */ |
||||||
|
# if @HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
/* This function is defined as a macro on MacOS X. */ |
||||||
|
# if defined __cplusplus && defined GNULIB_NAMESPACE |
||||||
|
# undef sigfillset |
||||||
|
# endif |
||||||
|
# else |
||||||
|
_GL_FUNCDECL_SYS (sigfillset, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigfillset, int, (sigset_t *set)); |
||||||
|
_GL_CXXALIASWARN (sigfillset); |
||||||
|
|
||||||
|
/* Return the set of those blocked signals that are pending. */ |
||||||
|
# if !@HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
_GL_FUNCDECL_SYS (sigpending, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigpending, int, (sigset_t *set)); |
||||||
|
_GL_CXXALIASWARN (sigpending); |
||||||
|
|
||||||
|
/* If OLD_SET is not NULL, put the current set of blocked signals in *OLD_SET.
|
||||||
|
Then, if SET is not NULL, affect the current set of blocked signals by |
||||||
|
combining it with *SET as indicated in OPERATION. |
||||||
|
In this implementation, you are not allowed to change a signal handler |
||||||
|
while the signal is blocked. */ |
||||||
|
# if !@HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
# define SIG_BLOCK 0 /* blocked_set = blocked_set | *set; */ |
||||||
|
# define SIG_SETMASK 1 /* blocked_set = *set; */ |
||||||
|
# define SIG_UNBLOCK 2 /* blocked_set = blocked_set & ~*set; */ |
||||||
|
_GL_FUNCDECL_SYS (sigprocmask, int, |
||||||
|
(int operation, const sigset_t *set, sigset_t *old_set)); |
||||||
|
# endif |
||||||
|
_GL_CXXALIAS_SYS (sigprocmask, int, |
||||||
|
(int operation, const sigset_t *set, sigset_t *old_set)); |
||||||
|
_GL_CXXALIASWARN (sigprocmask); |
||||||
|
|
||||||
|
/* Install the handler FUNC for signal SIG, and return the previous
|
||||||
|
handler. */ |
||||||
|
# ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
# endif |
||||||
|
# if !GNULIB_defined_function_taking_int_returning_void_t |
||||||
|
typedef void (*_gl_function_taking_int_returning_void_t) (int); |
||||||
|
# define GNULIB_defined_function_taking_int_returning_void_t 1 |
||||||
|
# endif |
||||||
|
# ifdef __cplusplus |
||||||
|
} |
||||||
|
# endif |
||||||
|
# if !@HAVE_POSIX_SIGNALBLOCKING@ |
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
||||||
|
# define signal rpl_signal |
||||||
|
# endif |
||||||
|
_GL_FUNCDECL_RPL (signal, _gl_function_taking_int_returning_void_t, |
||||||
|
(int sig, _gl_function_taking_int_returning_void_t func)); |
||||||
|
_GL_CXXALIAS_RPL (signal, _gl_function_taking_int_returning_void_t, |
||||||
|
(int sig, _gl_function_taking_int_returning_void_t func)); |
||||||
|
# else |
||||||
|
_GL_CXXALIAS_SYS (signal, _gl_function_taking_int_returning_void_t, |
||||||
|
(int sig, _gl_function_taking_int_returning_void_t func)); |
||||||
|
# endif |
||||||
|
_GL_CXXALIASWARN (signal); |
||||||
|
|
||||||
|
/* Raise signal SIG. */ |
||||||
|
# if !@HAVE_POSIX_SIGNALBLOCKING@ && GNULIB_defined_SIGPIPE |
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
||||||
|
# undef raise |
||||||
|
# define raise rpl_raise |
||||||
|
# endif |
||||||
|
_GL_FUNCDECL_RPL (raise, int, (int sig)); |
||||||
|
_GL_CXXALIAS_RPL (raise, int, (int sig)); |
||||||
|
# else |
||||||
|
_GL_CXXALIAS_SYS (raise, int, (int sig)); |
||||||
|
# endif |
||||||
|
_GL_CXXALIASWARN (raise); |
||||||
|
|
||||||
|
#elif defined GNULIB_POSIXCHECK |
||||||
|
# undef sigaddset |
||||||
|
# if HAVE_RAW_DECL_SIGADDSET |
||||||
|
_GL_WARN_ON_USE (sigaddset, "sigaddset is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigdelset |
||||||
|
# if HAVE_RAW_DECL_SIGDELSET |
||||||
|
_GL_WARN_ON_USE (sigdelset, "sigdelset is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigemptyset |
||||||
|
# if HAVE_RAW_DECL_SIGEMPTYSET |
||||||
|
_GL_WARN_ON_USE (sigemptyset, "sigemptyset is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigfillset |
||||||
|
# if HAVE_RAW_DECL_SIGFILLSET |
||||||
|
_GL_WARN_ON_USE (sigfillset, "sigfillset is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigismember |
||||||
|
# if HAVE_RAW_DECL_SIGISMEMBER |
||||||
|
_GL_WARN_ON_USE (sigismember, "sigismember is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigpending |
||||||
|
# if HAVE_RAW_DECL_SIGPENDING |
||||||
|
_GL_WARN_ON_USE (sigpending, "sigpending is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
# undef sigprocmask |
||||||
|
# if HAVE_RAW_DECL_SIGPROCMASK |
||||||
|
_GL_WARN_ON_USE (sigprocmask, "sigprocmask is unportable - " |
||||||
|
"use the gnulib module sigprocmask for portability"); |
||||||
|
# endif |
||||||
|
#endif /* @GNULIB_SIGPROCMASK@ */ |
||||||
|
|
||||||
|
|
||||||
|
#if @GNULIB_SIGACTION@ |
||||||
|
# if !@HAVE_SIGACTION@ |
||||||
|
|
||||||
|
# if !@HAVE_SIGINFO_T@ |
||||||
|
|
||||||
|
# if !GNULIB_defined_siginfo_types |
||||||
|
|
||||||
|
/* Present to allow compilation, but unsupported by gnulib. */ |
||||||
|
union sigval |
||||||
|
{ |
||||||
|
int sival_int; |
||||||
|
void *sival_ptr; |
||||||
|
}; |
||||||
|
|
||||||
|
/* Present to allow compilation, but unsupported by gnulib. */ |
||||||
|
struct siginfo_t |
||||||
|
{ |
||||||
|
int si_signo; |
||||||
|
int si_code; |
||||||
|
int si_errno; |
||||||
|
pid_t si_pid; |
||||||
|
uid_t si_uid; |
||||||
|
void *si_addr; |
||||||
|
int si_status; |
||||||
|
long si_band; |
||||||
|
union sigval si_value; |
||||||
|
}; |
||||||
|
typedef struct siginfo_t siginfo_t; |
||||||
|
|
||||||
|
# define GNULIB_defined_siginfo_types 1 |
||||||
|
# endif |
||||||
|
|
||||||
|
# endif /* !@HAVE_SIGINFO_T@ */ |
||||||
|
|
||||||
|
/* We assume that platforms which lack the sigaction() function also lack
|
||||||
|
the 'struct sigaction' type, and vice versa. */ |
||||||
|
|
||||||
|
# if !GNULIB_defined_struct_sigaction |
||||||
|
|
||||||
|
struct sigaction |
||||||
|
{ |
||||||
|
union |
||||||
|
{ |
||||||
|
void (*_sa_handler) (int); |
||||||
|
/* Present to allow compilation, but unsupported by gnulib. POSIX
|
||||||
|
says that implementations may, but not must, make sa_sigaction |
||||||
|
overlap with sa_handler, but we know of no implementation where |
||||||
|
they do not overlap. */ |
||||||
|
void (*_sa_sigaction) (int, siginfo_t *, void *); |
||||||
|
} _sa_func; |
||||||
|
sigset_t sa_mask; |
||||||
|
/* Not all POSIX flags are supported. */ |
||||||
|
int sa_flags; |
||||||
|
}; |
||||||
|
# define sa_handler _sa_func._sa_handler |
||||||
|
# define sa_sigaction _sa_func._sa_sigaction |
||||||
|
/* Unsupported flags are not present. */ |
||||||
|
# define SA_RESETHAND 1 |
||||||
|
# define SA_NODEFER 2 |
||||||
|
# define SA_RESTART 4 |
||||||
|
|
||||||
|
# define GNULIB_defined_struct_sigaction 1 |
||||||
|
# endif |
||||||
|
|
||||||
|
_GL_FUNCDECL_SYS (sigaction, int, (int, const struct sigaction *restrict, |
||||||
|
struct sigaction *restrict)); |
||||||
|
|
||||||
|
# elif !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ |
||||||
|
|
||||||
|
# define sa_sigaction sa_handler |
||||||
|
|
||||||
|
# endif /* !@HAVE_SIGACTION@, !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ */ |
||||||
|
|
||||||
|
_GL_CXXALIAS_SYS (sigaction, int, (int, const struct sigaction *restrict, |
||||||
|
struct sigaction *restrict)); |
||||||
|
_GL_CXXALIASWARN (sigaction); |
||||||
|
|
||||||
|
#elif defined GNULIB_POSIXCHECK |
||||||
|
# undef sigaction |
||||||
|
# if HAVE_RAW_DECL_SIGACTION |
||||||
|
_GL_WARN_ON_USE (sigaction, "sigaction is unportable - " |
||||||
|
"use the gnulib module sigaction for portability"); |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Some systems don't have SA_NODEFER. */ |
||||||
|
#ifndef SA_NODEFER |
||||||
|
# define SA_NODEFER 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#endif /* _@GUARD_PREFIX@_SIGNAL_H */ |
||||||
|
#endif /* _@GUARD_PREFIX@_SIGNAL_H */ |
||||||
|
#endif |
@ -0,0 +1,329 @@ |
|||||||
|
/* POSIX compatible signal blocking.
|
||||||
|
Copyright (C) 2006-2011 Free Software Foundation, Inc. |
||||||
|
Written by Bruno Haible <bruno@clisp.org>, 2006. |
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
#include <config.h> |
||||||
|
|
||||||
|
/* Specification. */ |
||||||
|
#include <signal.h> |
||||||
|
|
||||||
|
#include <errno.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdlib.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, |
||||||
|
where any handler is uninstalled prior to being invoked. This is |
||||||
|
true for Woe32 platforms. */ |
||||||
|
|
||||||
|
/* We use raw signal(), but also provide a wrapper rpl_signal() so
|
||||||
|
that applications can query or change a blocked signal. */ |
||||||
|
#undef signal |
||||||
|
|
||||||
|
/* Provide invalid signal numbers as fallbacks if the uncatchable
|
||||||
|
signals are not defined. */ |
||||||
|
#ifndef SIGKILL |
||||||
|
# define SIGKILL (-1) |
||||||
|
#endif |
||||||
|
#ifndef SIGSTOP |
||||||
|
# define SIGSTOP (-1) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
|
||||||
|
for the signal SIGABRT. Only one signal handler is stored for both |
||||||
|
SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */ |
||||||
|
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
||||||
|
# undef SIGABRT_COMPAT |
||||||
|
# define SIGABRT_COMPAT 6 |
||||||
|
#endif |
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT) |
||||||
|
#else |
||||||
|
# define SIGABRT_COMPAT_MASK 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef void (*handler_t) (int); |
||||||
|
|
||||||
|
/* Handling of gnulib defined signals. */ |
||||||
|
|
||||||
|
#if GNULIB_defined_SIGPIPE |
||||||
|
static handler_t SIGPIPE_handler = SIG_DFL; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if GNULIB_defined_SIGPIPE |
||||||
|
static handler_t |
||||||
|
ext_signal (int sig, handler_t handler) |
||||||
|
{ |
||||||
|
switch (sig) |
||||||
|
{ |
||||||
|
case SIGPIPE: |
||||||
|
{ |
||||||
|
handler_t old_handler = SIGPIPE_handler; |
||||||
|
SIGPIPE_handler = handler; |
||||||
|
return old_handler; |
||||||
|
} |
||||||
|
default: /* System defined signal */ |
||||||
|
return signal (sig, handler); |
||||||
|
} |
||||||
|
} |
||||||
|
# define signal ext_signal |
||||||
|
#endif |
||||||
|
|
||||||
|
int |
||||||
|
sigismember (const sigset_t *set, int sig) |
||||||
|
{ |
||||||
|
if (sig >= 0 && sig < NSIG) |
||||||
|
{ |
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
if (sig == SIGABRT_COMPAT) |
||||||
|
sig = SIGABRT; |
||||||
|
#endif |
||||||
|
|
||||||
|
return (*set >> sig) & 1; |
||||||
|
} |
||||||
|
else |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
sigemptyset (sigset_t *set) |
||||||
|
{ |
||||||
|
*set = 0; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
sigaddset (sigset_t *set, int sig) |
||||||
|
{ |
||||||
|
if (sig >= 0 && sig < NSIG) |
||||||
|
{ |
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
if (sig == SIGABRT_COMPAT) |
||||||
|
sig = SIGABRT; |
||||||
|
#endif |
||||||
|
|
||||||
|
*set |= 1U << sig; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
errno = EINVAL; |
||||||
|
return -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
sigdelset (sigset_t *set, int sig) |
||||||
|
{ |
||||||
|
if (sig >= 0 && sig < NSIG) |
||||||
|
{ |
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
if (sig == SIGABRT_COMPAT) |
||||||
|
sig = SIGABRT; |
||||||
|
#endif |
||||||
|
|
||||||
|
*set &= ~(1U << sig); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
errno = EINVAL; |
||||||
|
return -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int |
||||||
|
sigfillset (sigset_t *set) |
||||||
|
{ |
||||||
|
*set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* Set of currently blocked signals. */ |
||||||
|
static volatile sigset_t blocked_set /* = 0 */; |
||||||
|
|
||||||
|
/* Set of currently blocked and pending signals. */ |
||||||
|
static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */; |
||||||
|
|
||||||
|
/* Signal handler that is installed for blocked signals. */ |
||||||
|
static void |
||||||
|
blocked_handler (int sig) |
||||||
|
{ |
||||||
|
/* Reinstall the handler, in case the signal occurs multiple times
|
||||||
|
while blocked. There is an inherent race where an asynchronous |
||||||
|
signal in between when the kernel uninstalled the handler and |
||||||
|
when we reinstall it will trigger the default handler; oh |
||||||
|
well. */ |
||||||
|
signal (sig, blocked_handler); |
||||||
|
if (sig >= 0 && sig < NSIG) |
||||||
|
pending_array[sig] = 1; |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
sigpending (sigset_t *set) |
||||||
|
{ |
||||||
|
sigset_t pending = 0; |
||||||
|
int sig; |
||||||
|
|
||||||
|
for (sig = 0; sig < NSIG; sig++) |
||||||
|
if (pending_array[sig]) |
||||||
|
pending |= 1U << sig; |
||||||
|
*set = pending; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* The previous signal handlers.
|
||||||
|
Only the array elements corresponding to blocked signals are relevant. */ |
||||||
|
static volatile handler_t old_handlers[NSIG]; |
||||||
|
|
||||||
|
int |
||||||
|
sigprocmask (int operation, const sigset_t *set, sigset_t *old_set) |
||||||
|
{ |
||||||
|
if (old_set != NULL) |
||||||
|
*old_set = blocked_set; |
||||||
|
|
||||||
|
if (set != NULL) |
||||||
|
{ |
||||||
|
sigset_t new_blocked_set; |
||||||
|
sigset_t to_unblock; |
||||||
|
sigset_t to_block; |
||||||
|
|
||||||
|
switch (operation) |
||||||
|
{ |
||||||
|
case SIG_BLOCK: |
||||||
|
new_blocked_set = blocked_set | *set; |
||||||
|
break; |
||||||
|
case SIG_SETMASK: |
||||||
|
new_blocked_set = *set; |
||||||
|
break; |
||||||
|
case SIG_UNBLOCK: |
||||||
|
new_blocked_set = blocked_set & ~*set; |
||||||
|
break; |
||||||
|
default: |
||||||
|
errno = EINVAL; |
||||||
|
return -1; |
||||||
|
} |
||||||
|
to_unblock = blocked_set & ~new_blocked_set; |
||||||
|
to_block = new_blocked_set & ~blocked_set; |
||||||
|
|
||||||
|
if (to_block != 0) |
||||||
|
{ |
||||||
|
int sig; |
||||||
|
|
||||||
|
for (sig = 0; sig < NSIG; sig++) |
||||||
|
if ((to_block >> sig) & 1) |
||||||
|
{ |
||||||
|
pending_array[sig] = 0; |
||||||
|
if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR) |
||||||
|
blocked_set |= 1U << sig; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (to_unblock != 0) |
||||||
|
{ |
||||||
|
sig_atomic_t received[NSIG]; |
||||||
|
int sig; |
||||||
|
|
||||||
|
for (sig = 0; sig < NSIG; sig++) |
||||||
|
if ((to_unblock >> sig) & 1) |
||||||
|
{ |
||||||
|
if (signal (sig, old_handlers[sig]) != blocked_handler) |
||||||
|
/* The application changed a signal handler while the signal
|
||||||
|
was blocked, bypassing our rpl_signal replacement. |
||||||
|
We don't support this. */ |
||||||
|
abort (); |
||||||
|
received[sig] = pending_array[sig]; |
||||||
|
blocked_set &= ~(1U << sig); |
||||||
|
pending_array[sig] = 0; |
||||||
|
} |
||||||
|
else |
||||||
|
received[sig] = 0; |
||||||
|
|
||||||
|
for (sig = 0; sig < NSIG; sig++) |
||||||
|
if (received[sig]) |
||||||
|
raise (sig); |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* Install the handler FUNC for signal SIG, and return the previous
|
||||||
|
handler. */ |
||||||
|
handler_t |
||||||
|
rpl_signal (int sig, 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. */ |
||||||
|
if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP |
||||||
|
&& handler != SIG_ERR) |
||||||
|
{ |
||||||
|
#ifdef SIGABRT_COMPAT |
||||||
|
if (sig == SIGABRT_COMPAT) |
||||||
|
sig = SIGABRT; |
||||||
|
#endif |
||||||
|
|
||||||
|
if (blocked_set & (1U << sig)) |
||||||
|
{ |
||||||
|
/* POSIX states that sigprocmask and signal are both
|
||||||
|
async-signal-safe. This is not true of our |
||||||
|
implementation - there is a slight data race where an |
||||||
|
asynchronous interrupt on signal A can occur after we |
||||||
|
install blocked_handler but before we have updated |
||||||
|
old_handlers for signal B, such that handler A can see |
||||||
|
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]; |
||||||
|
old_handlers[sig] = handler; |
||||||
|
return result; |
||||||
|
} |
||||||
|
else |
||||||
|
return signal (sig, handler); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
errno = EINVAL; |
||||||
|
return SIG_ERR; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#if GNULIB_defined_SIGPIPE |
||||||
|
/* Raise the signal SIG. */ |
||||||
|
int |
||||||
|
rpl_raise (int sig) |
||||||
|
# undef raise |
||||||
|
{ |
||||||
|
switch (sig) |
||||||
|
{ |
||||||
|
case SIGPIPE: |
||||||
|
if (blocked_set & (1U << sig)) |
||||||
|
pending_array[sig] = 1; |
||||||
|
else |
||||||
|
{ |
||||||
|
handler_t handler = SIGPIPE_handler; |
||||||
|
if (handler == SIG_DFL) |
||||||
|
exit (128 + SIGPIPE); |
||||||
|
else if (handler != SIG_IGN) |
||||||
|
(*handler) (sig); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
default: /* System defined signal */ |
||||||
|
return raise (sig); |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,43 @@ |
|||||||
|
# sigaction.m4 serial 6 |
||||||
|
dnl Copyright (C) 2008-2011 Free Software Foundation, Inc. |
||||||
|
dnl This file is free software; the Free Software Foundation |
||||||
|
dnl gives unlimited permission to copy and/or distribute it, |
||||||
|
dnl with or without modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# Determine if sigaction interface is present. |
||||||
|
AC_DEFUN([gl_SIGACTION], |
||||||
|
[ |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
AC_CHECK_FUNCS_ONCE([sigaction]) |
||||||
|
if test $ac_cv_func_sigaction = yes; then |
||||||
|
AC_CHECK_MEMBERS([struct sigaction.sa_sigaction], , , |
||||||
|
[[#include <signal.h>]]) |
||||||
|
if test $ac_cv_member_struct_sigaction_sa_sigaction = no; then |
||||||
|
HAVE_STRUCT_SIGACTION_SA_SIGACTION=0 |
||||||
|
fi |
||||||
|
else |
||||||
|
HAVE_SIGACTION=0 |
||||||
|
fi |
||||||
|
]) |
||||||
|
|
||||||
|
# Prerequisites of the part of lib/signal.in.h and of lib/sigaction.c. |
||||||
|
AC_DEFUN([gl_PREREQ_SIGACTION], |
||||||
|
[ |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
AC_REQUIRE([AC_C_RESTRICT]) |
||||||
|
AC_REQUIRE([AC_TYPE_UID_T]) |
||||||
|
AC_REQUIRE([gl_PREREQ_SIG_HANDLER_H]) |
||||||
|
AC_CHECK_FUNCS_ONCE([sigaltstack siginterrupt]) |
||||||
|
AC_CHECK_TYPES([siginfo_t], [], [], [[ |
||||||
|
#include <signal.h> |
||||||
|
]]) |
||||||
|
if test $ac_cv_type_siginfo_t = no; then |
||||||
|
HAVE_SIGINFO_T=0 |
||||||
|
fi |
||||||
|
]) |
||||||
|
|
||||||
|
# Prerequisites of lib/sig-handler.h. |
||||||
|
AC_DEFUN([gl_PREREQ_SIG_HANDLER_H], |
||||||
|
[ |
||||||
|
AC_REQUIRE([AC_C_INLINE]) |
||||||
|
]) |
@ -0,0 +1,58 @@ |
|||||||
|
# signal_h.m4 serial 12 |
||||||
|
dnl Copyright (C) 2007-2011 Free Software Foundation, Inc. |
||||||
|
dnl This file is free software; the Free Software Foundation |
||||||
|
dnl gives unlimited permission to copy and/or distribute it, |
||||||
|
dnl with or without modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
AC_DEFUN([gl_SIGNAL_H], |
||||||
|
[ |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
gl_NEXT_HEADERS([signal.h]) |
||||||
|
|
||||||
|
# AIX declares sig_atomic_t to already include volatile, and C89 compilers |
||||||
|
# then choke on 'volatile sig_atomic_t'. C99 requires that it compile. |
||||||
|
AC_CHECK_TYPE([volatile sig_atomic_t], [], |
||||||
|
[HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=0], [[ |
||||||
|
#include <signal.h> |
||||||
|
]]) |
||||||
|
|
||||||
|
AC_REQUIRE([AC_TYPE_UID_T]) |
||||||
|
|
||||||
|
dnl Persuade glibc <signal.h> to define sighandler_t. |
||||||
|
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) |
||||||
|
AC_CHECK_TYPE([sighandler_t], [], [HAVE_SIGHANDLER_T=0], [[ |
||||||
|
#include <signal.h> |
||||||
|
]]) |
||||||
|
|
||||||
|
dnl Check for declarations of anything we want to poison if the |
||||||
|
dnl corresponding gnulib module is not in use. |
||||||
|
gl_WARN_ON_USE_PREPARE([[#include <signal.h> |
||||||
|
]], [sigaction sigaddset sigdelset sigemptyset sigfillset sigismember |
||||||
|
sigpending sigprocmask]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([gl_SIGNAL_MODULE_INDICATOR], |
||||||
|
[ |
||||||
|
dnl Use AC_REQUIRE here, so that the default settings are expanded once only. |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
gl_MODULE_INDICATOR_SET_VARIABLE([$1]) |
||||||
|
dnl Define it also as a C macro, for the benefit of the unit tests. |
||||||
|
gl_MODULE_INDICATOR_FOR_TESTS([$1]) |
||||||
|
]) |
||||||
|
|
||||||
|
AC_DEFUN([gl_SIGNAL_H_DEFAULTS], |
||||||
|
[ |
||||||
|
GNULIB_SIGNAL_H_SIGPIPE=0; AC_SUBST([GNULIB_SIGNAL_H_SIGPIPE]) |
||||||
|
GNULIB_SIGPROCMASK=0; AC_SUBST([GNULIB_SIGPROCMASK]) |
||||||
|
GNULIB_SIGACTION=0; AC_SUBST([GNULIB_SIGACTION]) |
||||||
|
dnl Assume proper GNU behavior unless another module says otherwise. |
||||||
|
HAVE_POSIX_SIGNALBLOCKING=1; AC_SUBST([HAVE_POSIX_SIGNALBLOCKING]) |
||||||
|
HAVE_SIGSET_T=1; AC_SUBST([HAVE_SIGSET_T]) |
||||||
|
HAVE_SIGINFO_T=1; AC_SUBST([HAVE_SIGINFO_T]) |
||||||
|
HAVE_SIGACTION=1; AC_SUBST([HAVE_SIGACTION]) |
||||||
|
HAVE_STRUCT_SIGACTION_SA_SIGACTION=1; |
||||||
|
AC_SUBST([HAVE_STRUCT_SIGACTION_SA_SIGACTION]) |
||||||
|
HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=1; |
||||||
|
AC_SUBST([HAVE_TYPE_VOLATILE_SIG_ATOMIC_T]) |
||||||
|
HAVE_SIGHANDLER_T=1; AC_SUBST([HAVE_SIGHANDLER_T]) |
||||||
|
]) |
@ -0,0 +1,40 @@ |
|||||||
|
# signalblocking.m4 serial 11 |
||||||
|
dnl Copyright (C) 2001-2002, 2006-2011 Free Software Foundation, Inc. |
||||||
|
dnl This file is free software; the Free Software Foundation |
||||||
|
dnl gives unlimited permission to copy and/or distribute it, |
||||||
|
dnl with or without modifications, as long as this notice is preserved. |
||||||
|
|
||||||
|
# Determine available signal blocking primitives. Three different APIs exist: |
||||||
|
# 1) POSIX: sigemptyset, sigaddset, sigprocmask |
||||||
|
# 2) SYSV: sighold, sigrelse |
||||||
|
# 3) BSD: sigblock, sigsetmask |
||||||
|
# For simplicity, here we check only for the POSIX signal blocking. |
||||||
|
AC_DEFUN([gl_SIGNALBLOCKING], |
||||||
|
[ |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
signals_not_posix= |
||||||
|
AC_EGREP_HEADER([sigset_t], [signal.h], , [signals_not_posix=1]) |
||||||
|
if test -z "$signals_not_posix"; then |
||||||
|
AC_CHECK_FUNC([sigprocmask], [gl_cv_func_sigprocmask=1]) |
||||||
|
fi |
||||||
|
if test -z "$gl_cv_func_sigprocmask"; then |
||||||
|
HAVE_POSIX_SIGNALBLOCKING=0 |
||||||
|
fi |
||||||
|
]) |
||||||
|
|
||||||
|
# Prerequisites of the part of lib/signal.in.h and of lib/sigprocmask.c. |
||||||
|
AC_DEFUN([gl_PREREQ_SIGPROCMASK], |
||||||
|
[ |
||||||
|
AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) |
||||||
|
AC_CHECK_TYPES([sigset_t], |
||||||
|
[gl_cv_type_sigset_t=yes], [gl_cv_type_sigset_t=no], |
||||||
|
[#include <signal.h> |
||||||
|
/* Mingw defines sigset_t not in <signal.h>, but in <sys/types.h>. */ |
||||||
|
#include <sys/types.h>]) |
||||||
|
if test $gl_cv_type_sigset_t != yes; then |
||||||
|
HAVE_SIGSET_T=0 |
||||||
|
fi |
||||||
|
dnl HAVE_SIGSET_T is 1 if the system lacks the sigprocmask function but has |
||||||
|
dnl the sigset_t type. |
||||||
|
AC_SUBST([HAVE_SIGSET_T]) |
||||||
|
]) |
Loading…
Reference in new issue