autoupdate
[gnulib.git] / lib / sigaction.c
index 9b0c92f..97eb76d 100644 (file)
@@ -1,5 +1,5 @@
 /* POSIX compatible signal blocking.
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008-2013 Free Software Foundation, Inc.
    Written by Eric Blake <ebb9@byu.net>, 2008.
 
    This program is free software: you can redistribute it and/or modify
@@ -24,7 +24,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 
-/* This implementation of sigaction is tailored to Woe32 behavior:
+/* This implementation of sigaction is tailored to native Windows 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,
    the situation by reading static storage in a signal handler, which
    POSIX warns is not generically async-signal-safe.  Oh well.
 
-   Additionally, SIGCHLD is not defined, so we don't implement
-   SA_NOCLDSTOP or SA_NOCLDWAIT; sigaltstack() is not present, so we
-   don't implement SA_ONSTACK; and siginterrupt() is not present, so
-   we don't implement SA_RESTART.  Supporting SA_SIGINFO is impossible
-   to do portably.
+   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 native Windows API 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
 # 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);
 
@@ -79,7 +91,7 @@ sigaction_handler (int sig)
     {
       /* Unexpected situation; be careful to avoid recursive abort.  */
       if (sig == SIGABRT)
-       signal (SIGABRT, SIG_DFL);
+        signal (SIGABRT, SIG_DFL);
       abort ();
     }
 
@@ -130,6 +142,11 @@ sigaction (int sig, const struct sigaction *restrict act,
       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