diff options
Diffstat (limited to 'src/sysdep.c')
-rw-r--r-- | src/sysdep.c | 111 |
1 files changed, 38 insertions, 73 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 42b8baf78e0..0f16d1a7645 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #define SYSTIME_INLINE EXTERN_INLINE #include <execinfo.h> -#include <signal.h> #include <stdio.h> #include <setjmp.h> #ifdef HAVE_PWD_H @@ -303,27 +302,34 @@ wait_for_termination_1 (pid_t pid, int interruptible) termination of subprocesses, perhaps involving a kernel bug too, but no idea what it is. Just as a hunch we signal SIGCHLD to see if that causes the problem to go away or get worse. */ - sigsetmask (sigmask (SIGCHLD)); + sigset_t sigchild_mask; + sigemptyset (&sigchild_mask); + sigaddset (&sigchild_mask, SIGCHLD); + pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0); + if (0 > kill (pid, 0)) { - sigsetmask (SIGEMPTYMASK); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); kill (getpid (), SIGCHLD); break; } if (wait_debugging) sleep (1); else - sigpause (SIGEMPTYMASK); + sigsuspend (&empty_mask); #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ #ifdef WINDOWSNT wait (0); break; #else /* not WINDOWSNT */ - sigblock (sigmask (SIGCHLD)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGCHLD); + pthread_sigmask (SIG_BLOCK, &blocked, 0); errno = 0; if (kill (pid, 0) == -1 && errno == ESRCH) { - sigunblock (sigmask (SIGCHLD)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); break; } @@ -457,11 +463,11 @@ child_setup_tty (int out) #endif /* not MSDOS */ -/* Record a signal code and the handler for it. */ +/* Record a signal code and the action for it. */ struct save_signal { int code; - void (*handler) (int); + struct sigaction action; }; static void save_signal_handlers (struct save_signal *); @@ -619,8 +625,9 @@ save_signal_handlers (struct save_signal *saved_handlers) { while (saved_handlers->code) { - saved_handlers->handler - = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); + struct sigaction action; + emacs_sigaction_init (&action, SIG_IGN); + sigaction (saved_handlers->code, &action, &saved_handlers->action); saved_handlers++; } } @@ -630,7 +637,7 @@ restore_signal_handlers (struct save_signal *saved_handlers) { while (saved_handlers->code) { - signal (saved_handlers->code, saved_handlers->handler); + sigaction (saved_handlers->code, &saved_handlers->action, 0); saved_handlers++; } } @@ -687,13 +694,17 @@ reset_sigio (int fd) void request_sigio (void) { + sigset_t unblocked; + if (noninteractive) return; + sigemptyset (&unblocked); #ifdef SIGWINCH - sigunblock (sigmask (SIGWINCH)); + sigaddset (&unblocked, SIGWINCH); #endif - sigunblock (sigmask (SIGIO)); + sigaddset (&unblocked, SIGIO); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); interrupts_deferred = 0; } @@ -701,6 +712,8 @@ request_sigio (void) void unrequest_sigio (void) { + sigset_t blocked; + if (noninteractive) return; @@ -709,10 +722,12 @@ unrequest_sigio (void) return; #endif + sigemptyset (&blocked); #ifdef SIGWINCH - sigblock (sigmask (SIGWINCH)); + sigaddset (&blocked, SIGWINCH); #endif - sigblock (sigmask (SIGIO)); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, 0); interrupts_deferred = 1; } @@ -1471,20 +1486,16 @@ init_system_name (void) } } -/* POSIX signals support - DJB */ -/* Anyone with POSIX signals should have ANSI C declarations */ - sigset_t empty_mask; -#ifndef WINDOWSNT - -signal_handler_t -sys_signal (int signal_number, signal_handler_t action) +/* Store into *ACTION a signal action suitable for Emacs, with handler + HANDLER. */ +void +emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) { - struct sigaction new_action, old_action; - sigemptyset (&new_action.sa_mask); - new_action.sa_handler = action; - new_action.sa_flags = 0; + sigemptyset (&action->sa_mask); + action->sa_handler = handler; + action->sa_flags = 0; #if defined (SA_RESTART) /* Emacs mostly works better with restartable system services. If this flag exists, we probably want to turn it on here. @@ -1501,54 +1512,8 @@ sys_signal (int signal_number, signal_handler_t action) # if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) if (noninteractive) # endif - new_action.sa_flags = SA_RESTART; + action->sa_flags = SA_RESTART; #endif - sigaction (signal_number, &new_action, &old_action); - return (old_action.sa_handler); -} - -#endif /* WINDOWSNT */ - -#ifndef __GNUC__ -/* If we're compiling with GCC, we don't need this function, since it - can be written as a macro. */ -sigset_t -sys_sigmask (int sig) -{ - sigset_t mask; - sigemptyset (&mask); - sigaddset (&mask, sig); - return mask; -} -#endif - -/* I'd like to have these guys return pointers to the mask storage in here, - but there'd be trouble if the code was saving multiple masks. I'll be - safe and pass the structure. It normally won't be more than 2 bytes - anyhow. - DJB */ - -sigset_t -sys_sigblock (sigset_t new_mask) -{ - sigset_t old_mask; - pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask); - return (old_mask); -} - -sigset_t -sys_sigunblock (sigset_t new_mask) -{ - sigset_t old_mask; - pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask); - return (old_mask); -} - -sigset_t -sys_sigsetmask (sigset_t new_mask) -{ - sigset_t old_mask; - pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask); - return (old_mask); } #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD |