diff --git a/src/atimer.c b/src/atimer.c index c205f658d74..72e33656b4a 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -18,10 +18,6 @@ along with GNU Emacs. If not, see . */ #include -#ifdef WINDOWSNT -#define raise(s) w32_raise(s) -#endif - #include "lisp.h" #include "keyboard.h" #include "syssignal.h" diff --git a/src/syssignal.h b/src/syssignal.h index 4a90ece68fe..84a2a6760e4 100644 --- a/src/syssignal.h +++ b/src/syssignal.h @@ -70,6 +70,11 @@ char const *safe_strsignal (int) ATTRIBUTE_CONST; # define SA_SIGINFO 0 #endif +#ifdef WINDOWSNT +#define raise(sig) w32_raise(sig) +int w32_raise (int); +#endif + #ifndef emacs_raise # define emacs_raise(sig) raise (sig) #endif diff --git a/src/w32proc.c b/src/w32proc.c index 57530b5d8e5..b89979c7314 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -63,8 +63,6 @@ along with GNU Emacs. If not, see . */ #include "w32term.h" #include "coding.h" -void w32_raise (int); - #define RVA_TO_PTR(var,section,filedata) \ ((void *)((section)->PointerToRawData \ + ((DWORD_PTR)(var) - (section)->VirtualAddress) \ @@ -169,7 +167,7 @@ sys_signal (int sig, signal_handler handler) /* SIGCHLD is needed for supporting subprocesses, see sys_kill below. SIGALRM and SIGPROF are used by setitimer. All the others are the only ones supported by the MS runtime. */ - if (!(sig == SIGINT || sig == SIGSEGV || sig == SIGILL + if (!(sig == SIGINT || sig == SIGSEGV || sig == SIGILL || sig == SIGBREAK || sig == SIGFPE || sig == SIGABRT || sig == SIGTERM || sig == SIGCHLD || sig == SIGALRM || sig == SIGPROF)) { @@ -313,19 +311,52 @@ sigismember (const sigset_t *set, int signo) return (*set & (1U << signo)) != 0; } -/* A fuller emulation of 'raise', which supports signals that MS - runtime doesn't know about. */ -void +/* A fuller emulation of 'raise', which supports signals that MS runtime + doesn't know about, and avoids the danger of invoking the + invalid-argument handler. syssignal.h redirects 'raise' to this. */ + +#undef raise + +int w32_raise (int signo) { - if (!(signo == SIGCHLD || signo == SIGALRM || signo == SIGPROF)) - raise (signo); + signal_handler handler; - /* Call the handler directly for the signals that we handle - ourselves. */ - signal_handler handler = sig_handlers[signo]; - if (!(handler == SIG_DFL || handler == SIG_IGN || handler == SIG_ERR)) - handler (signo); + switch (signo) + { + /* Signals supported by MS runtime: */ + case SIGINT: + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + return raise (signo); + /* For signals for which we have custom support in Emacs, call the + handler directly. */ + case SIGCHLD: + case SIGALRM: + case SIGPROF: + handler = sig_handlers[signo]; + /* Implementation note: SIG_DFL does nothing, since these signals + are not supported by the MS runtime. */ + if (handler == SIG_IGN || handler == SIG_DFL) + return 0; + else if (handler == SIG_ERR) + { + errno = EINVAL; + return -1; + } + sig_handlers[signo] = SIG_DFL; /* in case handler raises same signal */ + handler (signo); + if (sig_handlers[signo] == SIG_DFL) + sig_handlers[signo] = handler; + return 0; + default: /* Any unsupported signal. */ + errno = EINVAL; + return -1; + } } pid_t