#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,
# 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)
- return (*set >> sig) & 1;
+ {
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
+ return (*set >> sig) & 1;
+ }
else
return 0;
}
{
if (sig >= 0 && sig < NSIG)
{
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
*set |= 1U << sig;
return 0;
}
{
if (sig >= 0 && sig < NSIG)
{
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
*set &= ~(1U << sig);
return 0;
}
}
}
+
int
sigfillset (sigset_t *set)
{
- *set = (2U << (NSIG - 1)) - 1;
+ *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
return 0;
}
/* The previous signal handlers.
Only the array elements corresponding to blocked signals are relevant. */
-static volatile sa_handler_t old_handlers[NSIG];
+static volatile handler_t old_handlers[NSIG];
int
sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
/* Install the handler FUNC for signal SIG, and return the previous
handler. */
-sa_handler_t
-rpl_signal (int sig, sa_handler_t 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
stale information if it calls signal(B). Oh well -
signal handlers really shouldn't try to manipulate the
installed handlers of unrelated signals. */
- sa_handler_t result = old_handlers[sig];
+ handler_t result = old_handlers[sig];
old_handlers[sig] = handler;
return result;
}
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