=== modified file 'ChangeLog' --- ChangeLog 2012-09-02 11:13:24 +0000 +++ ChangeLog 2012-09-03 01:55:39 +0000 @@ -1,3 +1,10 @@ +2012-09-03 Paul Eggert + + Signal-handler cleanup (Bug#12327). + * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF): + Adjust to syssignal.h changes. + (SIGNAL_H_AB): Remove; no longer needed. + 2012-09-02 Jan Djärv * configure.ac (HAVE_GOBJECT): Check for gobject-2.0 (Bug#12332). === modified file 'configure.ac' --- configure.ac 2012-09-02 11:13:24 +0000 +++ configure.ac 2012-09-03 01:56:28 +0000 @@ -3450,7 +3450,7 @@ cygwin ) AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)]) dnl multi-line AC_DEFINEs are hard. :( - AC_DEFINE(PTY_OPEN, [ do { int dummy; SIGMASKTYPE mask; mask = sigblock (sigmask (SIGCHLD)); if (-1 == openpty (&fd, &dummy, pty_name, 0, 0)) fd = -1; sigsetmask (mask); if (fd >= 0) emacs_close (dummy); } while (0)]) + AC_DEFINE(PTY_OPEN, [ do { int dummy; sigset_t blocked, procmask; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); if (-1 == openpty (&fd, &dummy, pty_name, 0, 0)) fd = -1; pthread_sigmask (SIG_SETMASK, &procmask, 0); if (fd >= 0) emacs_close (dummy); } while (0)]) AC_DEFINE(PTY_NAME_SPRINTF, []) AC_DEFINE(PTY_TTY_NAME_SPRINTF, []) ;; @@ -3479,7 +3479,7 @@ AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)]) dnl Note that grantpt and unlockpt may fork. We must block SIGCHLD dnl to prevent sigchld_handler from intercepting the child's death. - AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname; sigblock (sigmask (SIGCHLD)); if (grantpt (fd) == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname(fd))) { sigunblock (sigmask (SIGCHLD)); close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); sigunblock (sigmask (SIGCHLD)); }]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname = 0; sigset_t blocked, procmask; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); if (grantpt (fd) != -1 && unlockpt (fd) != -1) ptyname = ptsname(fd); pthread_sigmask (SIG_SETMASK, &procmask, 0); if (!ptyname) { close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) dnl if HAVE_POSIX_OPENPT if test "x$ac_cv_func_posix_openpt" = xyes; then AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NOCTTY)]) @@ -3524,18 +3524,15 @@ ;; sol2* ) - dnl Uses sigblock/sigunblock rather than sighold/sigrelse, - dnl which appear to be BSD4.1 specific. It may also be appropriate - dnl for SVR4.x (x<2) but I'm not sure. fnf@cygnus.com dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler() dnl from intercepting that death. If any child but grantpt's should die dnl within, it should be caught after sigrelse(2). - AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; sigblock (sigmask (SIGCLD)); if (grantpt (fd) == -1) { emacs_close (fd); return -1; } sigunblock (sigmask (SIGCLD)); if (unlockpt (fd) == -1) { emacs_close (fd); return -1; } if (!(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked, procmask; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); grantpt_result = grantpt (fd); pthread_sigmask (SIG_SETMASK, &procmask, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) ;; unixware ) dnl Comments are as per sol2*. - AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; sigblock(sigmask(SIGCLD)); if (grantpt(fd) == -1) fatal("could not grant slave pty"); sigunblock(sigmask(SIGCLD)); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) + AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked, procmask; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); grantpt_result = grantpt (fd); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) ;; esac @@ -3811,13 +3808,6 @@ AC_DEFINE(XOS_NEEDS_TIME_H, 1, [Compensate for a bug in Xos.h on some systems, where it requires time.h.]) ;; - - netbsd | openbsd ) - dnl Greg A. Woods says we must include signal.h - dnl before syssignal.h is included, to work around interface conflicts - dnl that are handled with CPP __RENAME() macro in signal.h. - AC_DEFINE(SIGNAL_H_AHB, 1, [Define if AH_BOTTOM should include signal.h.]) - ;; esac === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-02 17:10:35 +0000 +++ src/ChangeLog 2012-09-03 08:02:33 +0000 @@ -1,3 +1,62 @@ +2012-09-03 Paul Eggert + + Signal-handler cleanup (Bug#12327). + Emacs's signal handlers were written in the old 4.2BSD style with + sigblock and sigmask and so forth, and this led to some + inefficiencies and confusion. Rewrite these to use + pthread_sigmask etc. without copying signal sets around. Also, + get rid of the confusing macros 'SIGNAL_THREAD_CHECK' and + 'signal', and instead use functions that do not attempt to take + over the system name space. This patch causes Emacs's text + segment to shrink by 0.7% on my platform, Fedora 17 x86-64. + * alloc.c, emacsgtkfixed.c, nsfns.m, widget.c, xmenu.c: + Do not include or "syssignal.h", as these + modules do not use signals. + * atimer.c, callproc.c, data.c, dispnew.c, emacs.c, floatfns.c: + * gtkutil.c, keyboard.c, process.c, sound.c, sysdep.c, term.c, xterm.c: + Do not include , as "syssignal.h" does that for us now. + * atimer.c (sigmask_atimers): New function. + (block_atimers, unblock_atimers): New functions, + replacing the old macros BLOCK_ATIMERS and UNBLOCK_ATIMERS. + All uses replaced. + * conf_post.h [SIGNAL_H_AHB]: Do not include ; + no longer needed here. + * emacs.c (main): Inspect existing signal handler with sigaction, + so that there's no need to block and unblock SIGHUP. + * sysdep.c, syssignal.h (SYSSIGNAL_INLINE): New macro. + * sysdep.c (struct save_signal): New member 'action', replacing + old member 'handler'. + (save_signal_handlers, restore_signal_handlers): + Use sigaction instead of 'signal' to save and restore. + (get_set_sighandler, set_sighandler) [!WINDOWSNT]: + New function. All users of 'signal' modified to use set_sighandler + if they're writeonly, and to use sys_signal if they're read+write. + (emacs_sigaction_init, forwarded_signal): New functions. + (sys_signal): Remove. All uses replaced by calls to sigaction + and emacs_sigaction_init, or by direct calls to 'signal'. + (sys_sigmask) [!__GNUC__]: Remove; no longer needed. + (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove; + all uses replaced by pthread_sigmask etc. calls. + * syssignal.h: Include and . + Use INLINE_HEADER_BEGIN, INLINE_HEADER_END. + (emacs_sigaction_init, forwarded_signal): New decls. + (SIGMASKTYPE): Remove. All uses replaced by its definiens, sigset_t. + (SIGEMPTYMASK): Remove; all uses replaced by its definiens, empty_mask. + (sigmask, sys_sigmask): Remove; no longer needed. + (sigpause): Remove. All uses replaced by its definiens, sigsuspend. + (sigblock, sigunblock, sigfree): + (sigsetmask) [!defined sigsetmask]: + Remove. All uses replaced by pthread_sigmask. + (signal): Remove. Its remaining uses (with SIG_DFL and SIG_IGN) + no longer need to be replaced, and its typical old uses + are now done via emacs_sigaction_init and sigaction. + (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove decls. + (sys_sigdel): Remove; unused. + (NSIG): Remove a FIXME; the code's fine. Remove an unnecessary ifdef. + (SIGNAL_THREAD_CHECK): Remove. All uses replaced by calls to + forwarded_signal. This is cleaner, because the caller can now + see that the check might immediately return from the caller. + 2012-09-02 Paul Eggert * emacs.c, eval.c: Use bool for boolean. === modified file 'src/alloc.c' --- src/alloc.c 2012-09-02 16:56:31 +0000 +++ src/alloc.c 2012-09-03 00:06:25 +0000 @@ -26,8 +26,6 @@ #include /* For CHAR_BIT. */ #include -#include - #ifdef HAVE_PTHREAD #include #endif @@ -42,7 +40,6 @@ #include "keyboard.h" #include "frame.h" #include "blockinput.h" -#include "syssignal.h" #include "termhooks.h" /* For struct terminal. */ #include #include === modified file 'src/atimer.c' --- src/atimer.c 2012-08-23 08:27:08 +0000 +++ src/atimer.c 2012-09-03 07:24:03 +0000 @@ -17,7 +17,6 @@ along with GNU Emacs. If not, see . */ #include -#include #include #include #include "lisp.h" @@ -51,8 +50,24 @@ /* Block/unblock SIGALRM. */ -#define BLOCK_ATIMERS sigblock (sigmask (SIGALRM)) -#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM)) +static void +sigmask_atimers (int how) +{ + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGALRM); + pthread_sigmask (how, &blocked, 0); +} +static void +block_atimers (void) +{ + sigmask_atimers (SIG_BLOCK); +} +static void +unblock_atimers (void) +{ + sigmask_atimers (SIG_UNBLOCK); +} /* Function prototypes. */ @@ -111,7 +126,7 @@ t->fn = fn; t->client_data = client_data; - BLOCK_ATIMERS; + block_atimers (); /* Compute the timer's expiration time. */ switch (type) @@ -132,7 +147,7 @@ /* Insert the timer in the list of active atimers. */ schedule_atimer (t); - UNBLOCK_ATIMERS; + unblock_atimers (); /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); @@ -148,7 +163,7 @@ { int i; - BLOCK_ATIMERS; + block_atimers (); for (i = 0; i < 2; ++i) { @@ -175,7 +190,7 @@ } } - UNBLOCK_ATIMERS; + unblock_atimers (); } @@ -206,7 +221,7 @@ void stop_other_atimers (struct atimer *t) { - BLOCK_ATIMERS; + block_atimers (); if (t) { @@ -231,7 +246,7 @@ stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; - UNBLOCK_ATIMERS; + unblock_atimers (); } @@ -246,7 +261,7 @@ struct atimer *t = atimers; struct atimer *next; - BLOCK_ATIMERS; + block_atimers (); atimers = stopped_atimers; stopped_atimers = NULL; @@ -257,7 +272,7 @@ t = next; } - UNBLOCK_ATIMERS; + unblock_atimers (); } } @@ -378,7 +393,8 @@ alarm_signal_handler (int signo) { #ifndef SYNC_INPUT - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; #endif pending_atimers = 1; @@ -397,9 +413,9 @@ { if (pending_atimers) { - BLOCK_ATIMERS; + block_atimers (); run_timers (); - UNBLOCK_ATIMERS; + unblock_atimers (); } } @@ -412,7 +428,9 @@ { if (on) { - signal (SIGALRM, alarm_signal_handler); + struct sigaction action; + emacs_sigaction_init (&action, alarm_signal_handler); + sigaction (SIGALRM, &action, 0); set_alarm (); } else @@ -423,8 +441,10 @@ void init_atimer (void) { + struct sigaction action; free_atimers = stopped_atimers = atimers = NULL; pending_atimers = 0; /* pending_signals is initialized in init_keyboard.*/ - signal (SIGALRM, alarm_signal_handler); + emacs_sigaction_init (&action, alarm_signal_handler); + sigaction (SIGALRM, &action, 0); } === modified file 'src/callproc.c' --- src/callproc.c 2012-08-25 03:11:12 +0000 +++ src/callproc.c 2012-09-03 06:50:19 +0000 @@ -19,7 +19,6 @@ #include -#include #include #include #include @@ -506,9 +505,6 @@ if (fd_output >= 0) fd1 = fd_output; -#if 0 /* Some systems don't have sigblock. */ - mask = sigblock (sigmask (SIGCHLD)); -#endif /* Record that we're about to create a synchronous process. */ synch_process_alive = 1; === modified file 'src/conf_post.h' --- src/conf_post.h 2012-08-20 16:48:10 +0000 +++ src/conf_post.h 2012-09-01 21:37:07 +0000 @@ -40,11 +40,6 @@ #endif #endif -#ifdef SIGNAL_H_AHB -#undef SIGNAL_H_AHB -#include -#endif - /* This silences a few compilation warnings on FreeBSD. */ #ifdef BSD_SYSTEM_AHB #undef BSD_SYSTEM_AHB === modified file 'src/data.c' --- src/data.c 2012-08-27 17:23:48 +0000 +++ src/data.c 2012-09-03 07:24:03 +0000 @@ -19,7 +19,6 @@ #include -#include #include #include @@ -3213,15 +3212,16 @@ static void arith_error (int signo) { - sigsetmask (SIGEMPTYMASK); - - SIGNAL_THREAD_CHECK (signo); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + if (forwarded_signal (signo)) + return; xsignal0 (Qarith_error); } void init_data (void) { + struct sigaction action; /* Don't do this if just dumping out. We don't want to call `signal' in this case so that we don't have trouble with dumping @@ -3230,5 +3230,6 @@ if (!initialized) return; #endif /* CANNOT_DUMP */ - signal (SIGFPE, arith_error); + emacs_sigaction_init (&action, arith_error); + sigaction (SIGFPE, &action, 0); } === modified file 'src/dispnew.c' --- src/dispnew.c 2012-09-01 06:38:52 +0000 +++ src/dispnew.c 2012-09-03 07:24:03 +0000 @@ -21,7 +21,6 @@ #define DISPEXTERN_INLINE EXTERN_INLINE -#include #include #include #include @@ -5561,8 +5560,11 @@ struct tty_display_info *tty; - signal (SIGWINCH, window_change_signal); - SIGNAL_THREAD_CHECK (signalnum); + struct sigaction action; + emacs_sigaction_init (&action, window_change_signal); + sigaction (SIGWINCH, &action, 0); + if (forwarded_signal (signalnum)) + return; /* The frame size change obviously applies to a single termcap-controlled terminal, but we can't decide which. @@ -6173,7 +6175,11 @@ #ifndef CANNOT_DUMP if (initialized) #endif /* CANNOT_DUMP */ - signal (SIGWINCH, window_change_signal); + { + struct sigaction action; + emacs_sigaction_init (&action, window_change_signal); + sigaction (SIGWINCH, &action, 0); + } #endif /* SIGWINCH */ /* If running as a daemon, no need to initialize any frames/terminal. */ === modified file 'src/emacs.c' --- src/emacs.c 2012-09-02 17:10:35 +0000 +++ src/emacs.c 2012-09-03 07:24:03 +0000 @@ -20,7 +20,6 @@ #include -#include #include #include @@ -297,7 +296,10 @@ void fatal_error_signal (int sig) { - SIGNAL_THREAD_CHECK (sig); + sigset_t unblocked; + + if (forwarded_signal (sig)) + return; fatal_error_code = sig; signal (sig, SIG_DFL); @@ -319,7 +321,9 @@ going to send is probably blocked, so we have to unblock it if we want to really receive it. */ #ifndef MSDOS - sigunblock (sigmask (fatal_error_code)); + sigemptyset (&unblocked); + sigaddset (&unblocked, fatal_error_code); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); #endif kill (getpid (), fatal_error_code); @@ -331,8 +335,11 @@ void memory_warning_signal (int sig) { - signal (sig, memory_warning_signal); - SIGNAL_THREAD_CHECK (sig); + struct sigaction action; + emacs_sigaction_init (&action, memory_warning_signal); + sigaction (sig, &action, 0); + if (forwarded_signal (sig)) + return; malloc_warning ("Operating system warns that virtual memory is running low.\n"); @@ -687,6 +694,7 @@ char dname_arg2[80]; #endif char *ch_to_dir; + struct sigaction fatal_error_action; #if GC_MARK_STACK stack_base = &dummy; @@ -1111,6 +1119,7 @@ } init_signals (); + emacs_sigaction_init (&fatal_error_action, fatal_error_signal); /* Don't catch SIGHUP if dumping. */ if (1 @@ -1119,13 +1128,17 @@ #endif ) { - sigblock (sigmask (SIGHUP)); /* In --batch mode, don't catch SIGHUP if already ignored. That makes nohup work. */ - if (! noninteractive - || signal (SIGHUP, SIG_IGN) != SIG_IGN) - signal (SIGHUP, fatal_error_signal); - sigunblock (sigmask (SIGHUP)); + bool catch_SIGHUP = !noninteractive; + if (!catch_SIGHUP) + { + struct sigaction old_action; + sigaction (SIGHUP, 0, &old_action); + catch_SIGHUP = old_action.sa_handler != SIG_IGN; + } + if (catch_SIGHUP) + sigaction (SIGHUP, &fatal_error_action, 0); } if ( @@ -1139,9 +1152,9 @@ /* Don't catch these signals in batch mode if dumping. On some machines, this sets static data that would make signal fail to work right when the dumped Emacs is run. */ - signal (SIGQUIT, fatal_error_signal); - signal (SIGILL, fatal_error_signal); - signal (SIGTRAP, fatal_error_signal); + sigaction (SIGQUIT, &fatal_error_action, 0); + sigaction (SIGILL, &fatal_error_action, 0); + sigaction (SIGTRAP, &fatal_error_action, 0); #ifdef SIGUSR1 add_user_signal (SIGUSR1, "sigusr1"); #endif @@ -1149,68 +1162,73 @@ add_user_signal (SIGUSR2, "sigusr2"); #endif #ifdef SIGABRT - signal (SIGABRT, fatal_error_signal); + sigaction (SIGABRT, &fatal_error_action, 0); #endif #ifdef SIGHWE - signal (SIGHWE, fatal_error_signal); + sigaction (SIGHWE, &fatal_error_action, 0); #endif #ifdef SIGPRE - signal (SIGPRE, fatal_error_signal); + sigaction (SIGPRE, &fatal_error_action, 0); #endif #ifdef SIGORE - signal (SIGORE, fatal_error_signal); + sigaction (SIGORE, &fatal_error_action, 0); #endif #ifdef SIGUME - signal (SIGUME, fatal_error_signal); + sigaction (SIGUME, &fatal_error_action, 0); #endif #ifdef SIGDLK - signal (SIGDLK, fatal_error_signal); + sigaction (SIGDLK, &fatal_error_action, 0); #endif #ifdef SIGCPULIM - signal (SIGCPULIM, fatal_error_signal); + sigaction (SIGCPULIM, &fatal_error_action, 0); #endif #ifdef SIGIOT /* This is missing on some systems - OS/2, for example. */ - signal (SIGIOT, fatal_error_signal); + sigaction (SIGIOT, &fatal_error_action, 0); #endif #ifdef SIGEMT - signal (SIGEMT, fatal_error_signal); + sigaction (SIGEMT, &fatal_error_action, 0); #endif - signal (SIGFPE, fatal_error_signal); + sigaction (SIGFPE, &fatal_error_action, 0); #ifdef SIGBUS - signal (SIGBUS, fatal_error_signal); + sigaction (SIGBUS, &fatal_error_action, 0); #endif - signal (SIGSEGV, fatal_error_signal); + sigaction (SIGSEGV, &fatal_error_action, 0); #ifdef SIGSYS - signal (SIGSYS, fatal_error_signal); + sigaction (SIGSYS, &fatal_error_action, 0); #endif /* May need special treatment on MS-Windows. See http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html Please update the doc of kill-emacs, kill-emacs-hook, and NEWS if you change this. */ - if (noninteractive) signal (SIGINT, fatal_error_signal); - signal (SIGTERM, fatal_error_signal); + if (noninteractive) + sigaction (SIGINT, &fatal_error_action, 0); + sigaction (SIGTERM, &fatal_error_action, 0); #ifdef SIGXCPU - signal (SIGXCPU, fatal_error_signal); + sigaction (SIGXCPU, &fatal_error_action, 0); #endif #ifdef SIGXFSZ - signal (SIGXFSZ, fatal_error_signal); + sigaction (SIGXFSZ, &fatal_error_action, 0); #endif /* SIGXFSZ */ #ifdef SIGDANGER /* This just means available memory is getting low. */ - signal (SIGDANGER, memory_warning_signal); + { + struct sigaction action; + emacs_sigaction_init (&action, memory_warning_signal); + sigaction (SIGDANGER, &action, 0); + } #endif #ifdef AIX /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ - signal (SIGXCPU, fatal_error_signal); - signal (SIGIOINT, fatal_error_signal); - signal (SIGGRANT, fatal_error_signal); - signal (SIGRETRACT, fatal_error_signal); - signal (SIGSOUND, fatal_error_signal); - signal (SIGMSG, fatal_error_signal); + sigaction (SIGXCPU, &fatal_error_action, 0); + sigaction (SIGIOINT, &fatal_error_action, 0); + sigaction (SIGGRANT, &fatal_error_action, 0); + sigaction (SIGRETRACT, &fatal_error_action, 0); + sigaction (SIGSOUND, &fatal_error_action, 0); + sigaction (SIGMSG, &fatal_error_action, 0); #endif /* AIX */ } === modified file 'src/emacsgtkfixed.c' --- src/emacsgtkfixed.c 2012-04-23 07:34:29 +0000 +++ src/emacsgtkfixed.c 2012-09-01 21:37:07 +0000 @@ -21,7 +21,6 @@ #include #include "emacsgtkfixed.h" -#include #include #include #include "lisp.h" === modified file 'src/floatfns.c' --- src/floatfns.c 2012-07-17 02:56:00 +0000 +++ src/floatfns.c 2012-09-03 07:24:03 +0000 @@ -48,7 +48,6 @@ */ #include -#include #include #include "lisp.h" #include "syssignal.h" @@ -955,13 +954,18 @@ fatal_error_signal (signo); #ifdef BSD_SYSTEM - sigsetmask (SIGEMPTYMASK); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); #else /* Must reestablish handler each time it is called. */ - signal (SIGILL, float_error); + { + struct sigaction action; + emacs_sigaction_init (&action, float_error); + sigaction (SIGILL, &action, 0); + } #endif /* BSD_SYSTEM */ - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; in_float = 0; xsignal1 (Qarith_error, float_error_arg); @@ -1007,7 +1011,9 @@ init_floatfns (void) { #ifdef FLOAT_CATCH_SIGILL - signal (SIGILL, float_error); + struct sigaction action; + emacs_sigaction_init (&action, float_error); + sigaction (SIGILL, &action, 0); #endif in_float = 0; } === modified file 'src/gtkutil.c' --- src/gtkutil.c 2012-09-02 16:56:31 +0000 +++ src/gtkutil.c 2012-09-03 06:50:19 +0000 @@ -21,7 +21,6 @@ #ifdef USE_GTK #include -#include #include #include @@ -1979,7 +1978,10 @@ /* I really don't know why this is needed, but without this the GLIBC add on library linuxthreads hangs when the Gnome file chooser backend creates threads. */ - sigblock (sigmask (__SIGRTMIN)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, __SIGRTMIN); + pthread_sigmask (SIG_BLOCK, &blocked, 0); #endif /* HAVE_PTHREAD */ #ifdef HAVE_GTK_FILE_SELECTION_NEW @@ -2001,7 +2003,7 @@ filesel_done = xg_dialog_run (f, w); #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigunblock (sigmask (__SIGRTMIN)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); #endif if (filesel_done == GTK_RESPONSE_OK) @@ -2056,7 +2058,10 @@ Lisp_Object font = Qnil; #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigblock (sigmask (__SIGRTMIN)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, __SIGRTMIN); + pthread_sigmask (SIG_BLOCK, &blocked, 0); #endif /* HAVE_PTHREAD */ w = gtk_font_chooser_dialog_new @@ -2085,7 +2090,7 @@ done = xg_dialog_run (f, w); #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigunblock (sigmask (__SIGRTMIN)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); #endif if (done == GTK_RESPONSE_OK) === modified file 'src/keyboard.c' --- src/keyboard.c 2012-09-02 16:56:31 +0000 +++ src/keyboard.c 2012-09-03 07:24:03 +0000 @@ -21,7 +21,6 @@ #define KEYBOARD_INLINE EXTERN_INLINE -#include #include #include #include "lisp.h" @@ -3681,7 +3680,7 @@ if (immediate_quit && NILP (Vinhibit_quit)) { immediate_quit = 0; - sigfree (); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); QUIT; } } @@ -3833,7 +3832,11 @@ unhold_keyboard_input (); #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + { + struct sigaction action; + emacs_sigaction_init (&action, input_available_signal); + sigaction (SIGIO, &action, 0); + } #endif /* SIGIO */ start_polling (); } @@ -6781,10 +6784,12 @@ #ifdef SIGIO if (interrupt_input) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGIO)); + sigset_t blocked, procmask; + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, &procmask); read_avail_input (expected); - sigsetmask (mask); + pthread_sigmask (SIG_SETMASK, &procmask, 0); } else #ifdef POLL_FOR_INPUT @@ -6793,10 +6798,12 @@ it's always set. */ if (!interrupt_input && poll_suppress_count == 0) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGALRM)); + sigset_t blocked, procmask; + sigemptyset (&blocked); + sigaddset (&blocked, SIGALRM); + pthread_sigmask (SIG_BLOCK, &blocked, &procmask); read_avail_input (expected); - sigsetmask (mask); + pthread_sigmask (SIG_SETMASK, &procmask, 0); } else #endif @@ -6832,10 +6839,12 @@ #ifdef SIGIO if (interrupt_input) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGIO)); + sigset_t blocked, procmask; + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, &procmask); kbd_buffer_store_event (&event); - sigsetmask (mask); + pthread_sigmask (SIG_SETMASK, &procmask, 0); } else #endif @@ -7240,7 +7249,8 @@ { /* Must preserve main program's value of errno. */ int old_errno = errno; - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; #ifdef SYNC_INPUT interrupt_input_pending = 1; @@ -7296,6 +7306,7 @@ void add_user_signal (int sig, const char *name) { + struct sigaction action; struct user_signal_info *p; for (p = user_signals; p; p = p->next) @@ -7310,7 +7321,8 @@ p->next = user_signals; user_signals = p; - signal (sig, handle_user_signal); + emacs_sigaction_init (&action, handle_user_signal); + sigaction (sig, &action, 0); } static void @@ -7320,7 +7332,8 @@ struct user_signal_info *p; const char *special_event_name = NULL; - SIGNAL_THREAD_CHECK (sig); + if (forwarded_signal (sig)) + return; if (SYMBOLP (Vdebug_on_event)) special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event)); @@ -7381,7 +7394,7 @@ for (p = user_signals; p; p = p->next) if (p->npending > 0) { - SIGMASKTYPE mask; + sigset_t blocked, procmask; if (nstored == 0) { @@ -7391,7 +7404,10 @@ } nstored += p->npending; - mask = sigblock (sigmask (p->sig)); + sigemptyset (&blocked); + sigaddset (&blocked, p->sig); + pthread_sigmask (SIG_BLOCK, &blocked, &procmask); + do { buf.code = p->sig; @@ -7399,7 +7415,8 @@ p->npending--; } while (p->npending > 0); - sigsetmask (mask); + + pthread_sigmask (SIG_SETMASK, &procmask, 0); } return nstored; @@ -10783,7 +10800,8 @@ int old_errno = errno; struct terminal *terminal; - SIGNAL_THREAD_CHECK (signalnum); + if (forwarded_signal (signalnum)) + return; /* See if we have an active terminal on our controlling tty. */ terminal = get_named_tty ("/dev/tty"); @@ -10840,7 +10858,10 @@ /* If SIGINT isn't blocked, don't let us be interrupted by another SIGINT, it might be harmful due to non-reentrancy in I/O functions. */ - sigblock (sigmask (SIGINT)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGINT); + pthread_sigmask (SIG_BLOCK, &blocked, 0); fflush (stdout); reset_all_sys_modes (); @@ -10911,7 +10932,7 @@ #endif /* not MSDOS */ fflush (stdout); init_all_sys_modes (); - sigfree (); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); } else { @@ -10924,7 +10945,7 @@ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; immediate_quit = 0; - sigfree (); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); saved = gl_state; GCPRO4 (saved.object, saved.global_code, saved.current_syntax_table, saved.old_prop); @@ -10969,7 +10990,7 @@ if (!from_signal && EQ (Vquit_flag, Qkill_emacs)) Fkill_emacs (Qnil); - sigfree (); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); /* Prevent another signal from doing this before we finish. */ clear_waiting_for_input (); input_pending = 0; @@ -11404,17 +11425,23 @@ SIGINT. There is special code in interrupt_signal to exit Emacs on SIGINT when there are no termcap frames on the controlling terminal. */ - signal (SIGINT, interrupt_signal); + struct sigaction action; + emacs_sigaction_init (&action, interrupt_signal); + sigaction (SIGINT, &action, 0); #ifndef DOS_NT /* For systems with SysV TERMIO, C-g is set up for both SIGINT and SIGQUIT and we can't tell which one it will give us. */ - signal (SIGQUIT, interrupt_signal); + sigaction (SIGQUIT, &action, 0); #endif /* not DOS_NT */ } /* Note SIGIO has been undef'd if FIONREAD is missing. */ #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + { + struct sigaction action; + emacs_sigaction_init (&action, input_available_signal); + sigaction (SIGIO, &action, 0); + } #endif /* SIGIO */ /* Use interrupt input by default, if it works and noninterrupt input @@ -11426,7 +11453,7 @@ interrupt_input = 0; #endif - sigfree (); + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); dribble = 0; if (keyboard_init_hook) === modified file 'src/nsfns.m' --- src/nsfns.m 2012-08-17 23:38:43 +0000 +++ src/nsfns.m 2012-09-01 21:37:07 +0000 @@ -30,7 +30,6 @@ interpretation of even the system includes. */ #include -#include #include #include #include === modified file 'src/process.c' --- src/process.c 2012-09-02 17:10:35 +0000 +++ src/process.c 2012-09-03 07:24:03 +0000 @@ -23,7 +23,6 @@ #define PROCESS_INLINE EXTERN_INLINE -#include #include #include #include @@ -1603,8 +1602,7 @@ #if !defined (WINDOWSNT) && defined (FD_CLOEXEC) int wait_child_setup[2]; #endif - sigset_t procmask; - sigset_t blocked; + sigset_t blocked, procmask; struct sigaction sigint_action; struct sigaction sigquit_action; struct sigaction sigpipe_action; @@ -1756,12 +1754,6 @@ int xforkin = forkin; int xforkout = forkout; -#if 0 /* This was probably a mistake--it duplicates code later on, - but fails to handle all the cases. */ - /* Make sure SIGCHLD is not blocked in the child. */ - sigsetmask (SIGEMPTYMASK); -#endif - /* Make the pty be the controlling terminal of the process. */ #ifdef HAVE_PTYS /* First, disconnect its current controlling terminal. */ @@ -5429,8 +5421,12 @@ static void send_process_trap (int ignore) { - SIGNAL_THREAD_CHECK (SIGPIPE); - sigunblock (sigmask (SIGPIPE)); + sigset_t unblocked; + if (forwarded_signal (SIGPIPE)) + return; + sigemptyset (&unblocked); + sigaddset (&unblocked, SIGPIPE); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); longjmp (send_process_frame, 1); } @@ -5524,7 +5520,7 @@ struct Lisp_Process *p = XPROCESS (proc); ssize_t rv; struct coding_system *coding; - void (*volatile old_sigpipe) (int); + struct sigaction old_sigpipe_action; if (p->raw_status_new) update_status (p); @@ -5663,7 +5659,9 @@ /* Send this batch, using one or more write calls. */ ptrdiff_t written = 0; int outfd = p->outfd; - old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); + struct sigaction action; + emacs_sigaction_init (&action, send_process_trap); + sigaction (SIGPIPE, &action, &old_sigpipe_action); #ifdef DATAGRAM_SOCKETS if (DATAGRAM_CHAN_P (outfd)) { @@ -5674,7 +5672,7 @@ written = rv; else if (errno == EMSGSIZE) { - signal (SIGPIPE, old_sigpipe); + sigaction (SIGPIPE, &old_sigpipe_action, 0); report_file_error ("sending datagram", Fcons (proc, Qnil)); } @@ -5699,7 +5697,7 @@ } #endif } - signal (SIGPIPE, old_sigpipe); + sigaction (SIGPIPE, &old_sigpipe_action, 0); if (rv < 0) { @@ -5759,7 +5757,7 @@ } else { - signal (SIGPIPE, old_sigpipe); + sigaction (SIGPIPE, &old_sigpipe_action, 0); proc = process_sent_to; p = XPROCESS (proc); p->raw_status_new = 0; @@ -6404,7 +6402,8 @@ Lisp_Object proc; struct Lisp_Process *p; - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; while (1) { @@ -7387,7 +7386,11 @@ #ifndef CANNOT_DUMP if (! noninteractive || initialized) #endif - signal (SIGCHLD, sigchld_handler); + { + struct sigaction action; + emacs_sigaction_init (&action, sigchld_handler); + sigaction (SIGCHLD, &action, 0); + } #endif FD_ZERO (&input_wait_mask); === modified file 'src/sound.c' --- src/sound.c 2012-07-29 08:18:29 +0000 +++ src/sound.c 2012-09-03 06:50:19 +0000 @@ -48,7 +48,6 @@ #include "lisp.h" #include "dispextern.h" #include "atimer.h" -#include #include "syssignal.h" /* END: Common Includes */ @@ -316,7 +315,12 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + { + sigset_t unblocked; + sigemptyset (&unblocked); + sigaddset (&unblocked, SIGIO); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); + } #endif if (saved_errno != 0) error ("%s: %s", msg, strerror (saved_errno)); @@ -728,6 +732,9 @@ vox_configure (struct sound_device *sd) { int val; +#ifdef SIGIO + sigset_t blocked; +#endif eassert (sd->fd >= 0); @@ -736,7 +743,9 @@ troubles. */ turn_on_atimers (0); #ifdef SIGIO - sigblock (sigmask (SIGIO)); + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, 0); #endif val = sd->format; @@ -770,7 +779,7 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); #endif } @@ -786,7 +795,10 @@ be interrupted by a signal. Block the ones we know to cause troubles. */ #ifdef SIGIO - sigblock (sigmask (SIGIO)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGIO); + pthread_sigmask (SIG_BLOCK, &blocked, 0); #endif turn_on_atimers (0); @@ -795,7 +807,7 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); #endif /* Close the device. */ === modified file 'src/sysdep.c' --- src/sysdep.c 2012-09-01 01:13:50 +0000 +++ src/sysdep.c 2012-09-03 07:38:38 +0000 @@ -19,9 +19,9 @@ #include +#define SYSSIGNAL_INLINE EXTERN_INLINE #define SYSTIME_INLINE EXTERN_INLINE -#include #include #include #ifdef HAVE_PWD_H @@ -302,27 +302,34 @@ 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; } @@ -456,11 +463,11 @@ #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 *); @@ -618,8 +625,9 @@ { 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++; } } @@ -629,7 +637,7 @@ { while (saved_handlers->code) { - signal (saved_handlers->code, saved_handlers->handler); + sigaction (saved_handlers->code, &saved_handlers->action, 0); saved_handlers++; } } @@ -686,13 +694,17 @@ 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; } @@ -700,6 +712,8 @@ void unrequest_sigio (void) { + sigset_t blocked; + if (noninteractive) return; @@ -708,10 +722,12 @@ 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; } @@ -1470,20 +1486,16 @@ } } -/* 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. @@ -1500,57 +1512,31 @@ # if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) if (noninteractive) # endif - new_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); -} - - + action->sa_flags = SA_RESTART; +#endif +} + +#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD +/* POSIX says any thread can receive the signal. On GNU/Linux that is + not true, but for other systems (FreeBSD at least) it is. So + direct the signal to the correct thread and block it from this thread. */ +bool +forwarded_signal (int signo) +{ + if (pthread_equal (pthread_self (), main_thread)) + return 0; + else + { + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, signo); + pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_kill (main_thread, signo); + return 1; + } +} +#endif + #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST static char *my_sys_siglist[NSIG]; # ifdef sys_siglist === modified file 'src/syssignal.h' --- src/syssignal.h 2012-07-13 01:19:06 +0000 +++ src/syssignal.h 2012-09-03 07:38:38 +0000 @@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ +#include +#include + extern void init_signals (void); #ifdef HAVE_PTHREAD @@ -26,63 +29,21 @@ #define FORWARD_SIGNAL_TO_MAIN_THREAD #endif -/* Don't #include . That header should always be #included - before "config.h", because some configuration files (like s/hpux.h) - indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file - #includes , then that will re-#define SIGIO and confuse - things. */ -/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */ - -#define SIGMASKTYPE sigset_t - -#define SIGEMPTYMASK (empty_mask) +INLINE_HEADER_BEGIN +#ifndef SYSSIGNAL_INLINE +# define SYSSIGNAL_INLINE INLINE +#endif + extern sigset_t empty_mask; -/* POSIX pretty much destroys any possibility of writing sigmask as a - macro in standard C. We always define our own version because the - predefined macro in Glibc 2.1 is only provided for compatibility for old - programs that use int as signal mask type. */ -#undef sigmask -#ifdef __GNUC__ -#define sigmask(SIG) \ - ({ \ - sigset_t _mask; \ - sigemptyset (&_mask); \ - sigaddset (&_mask, SIG); \ - _mask; \ - }) -#else /* ! defined (__GNUC__) */ -extern sigset_t sys_sigmask (); -#define sigmask(SIG) (sys_sigmask (SIG)) -#endif /* ! defined (__GNUC__) */ - -#undef sigpause -#define sigpause(MASK) sigsuspend (&(MASK)) - -#define sigblock(SIG) sys_sigblock (SIG) -#define sigunblock(SIG) sys_sigunblock (SIG) -#ifndef sigsetmask -#define sigsetmask(SIG) sys_sigsetmask (SIG) -#endif -#undef signal -#define signal(SIG,ACT) sys_signal(SIG,ACT) - -/* Whether this is what all systems want or not, this is what - appears to be assumed in the source, for example data.c:arith_error. */ typedef void (*signal_handler_t) (int); -signal_handler_t sys_signal (int signal_number, signal_handler_t action); -sigset_t sys_sigblock (sigset_t new_mask); -sigset_t sys_sigunblock (sigset_t new_mask); -sigset_t sys_sigsetmask (sigset_t new_mask); +extern void emacs_sigaction_init (struct sigaction *, signal_handler_t); + #if ! (defined TIOCNOTTY || defined USG5 || defined CYGWIN) _Noreturn void croak (char *); #endif -#define sys_sigdel(MASK,SIG) sigdelset (&MASK,SIG) - -#define sigfree() sigsetmask (SIGEMPTYMASK) - #if defined (SIGIO) && defined (BROKEN_SIGIO) # undef SIGIO #endif @@ -97,12 +58,8 @@ #undef SIGPTY #endif - -/* FIXME? Emacs only defines NSIG_MINIMUM on some platforms? */ #if NSIG < NSIG_MINIMUM -# ifdef NSIG -# undef NSIG -# endif +# undef NSIG # define NSIG NSIG_MINIMUM #endif @@ -133,24 +90,9 @@ #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD extern pthread_t main_thread; -#define SIGNAL_THREAD_CHECK(signo) \ - do { \ - if (!pthread_equal (pthread_self (), main_thread)) \ - { \ - /* POSIX says any thread can receive the signal. On GNU/Linux \ - that is not true, but for other systems (FreeBSD at least) \ - it is. So direct the signal to the correct thread and block \ - it from this thread. */ \ - sigset_t new_mask; \ - \ - sigemptyset (&new_mask); \ - sigaddset (&new_mask, signo); \ - pthread_sigmask (SIG_BLOCK, &new_mask, 0); \ - pthread_kill (main_thread, signo); \ - return; \ - } \ - } while (0) +extern bool forwarded_signal (int); +#else +SYSSIGNAL_INLINE bool forwarded_signal (int signo) { return 0; } +#endif -#else /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ -#define SIGNAL_THREAD_CHECK(signo) -#endif /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ +INLINE_HEADER_END === modified file 'src/term.c' --- src/term.c 2012-08-31 10:53:19 +0000 +++ src/term.c 2012-09-03 06:50:19 +0000 @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "lisp.h" @@ -2932,7 +2931,10 @@ no_controlling_tty = 1; #else #ifdef TIOCNOTTY /* Try BSD ioctls. */ - sigblock (sigmask (SIGTTOU)); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGTTOU); + pthread_sigmask (SIG_BLOCK, &blocked, 0); fd = emacs_open (DEV_TTY, O_RDWR, 0); if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1) { @@ -2940,7 +2942,7 @@ } if (fd != -1) emacs_close (fd); - sigunblock (sigmask (SIGTTOU)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); #else /* Unknown system. */ croak (); @@ -2971,6 +2973,7 @@ struct tty_display_info *tty = NULL; struct terminal *terminal = NULL; int ctty = 0; /* 1 if asked to open controlling tty. */ + sigset_t blocked; if (!terminal_type) maybe_fatal (must_succeed, 0, @@ -3074,9 +3077,11 @@ /* On some systems, tgetent tries to access the controlling terminal. */ - sigblock (sigmask (SIGTTOU)); + sigemptyset (&blocked); + sigaddset (&blocked, SIGTTOU); + pthread_sigmask (SIG_BLOCK, &blocked, 0); status = tgetent (tty->termcap_term_buffer, terminal_type); - sigunblock (sigmask (SIGTTOU)); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (status < 0) { === modified file 'src/widget.c' --- src/widget.c 2012-09-02 16:56:31 +0000 +++ src/widget.c 2012-09-03 00:06:25 +0000 @@ -50,9 +50,6 @@ #include #include "../lwlib/lwlib.h" -#include -#include "syssignal.h" - #include "character.h" #include "font.h" === modified file 'src/xmenu.c' --- src/xmenu.c 2012-08-17 21:52:15 +0000 +++ src/xmenu.c 2012-09-01 21:37:07 +0000 @@ -32,11 +32,6 @@ #include -#if 0 /* Why was this included? And without syssignal.h? */ -/* On 4.3 this loses if it comes after xterm.h. */ -#include -#endif - #include #include === modified file 'src/xterm.c' --- src/xterm.c 2012-09-02 17:10:35 +0000 +++ src/xterm.c 2012-09-03 07:24:03 +0000 @@ -21,7 +21,6 @@ /* Xt features made by Fred Pierresteguy. */ #include -#include #include #include @@ -29,9 +28,6 @@ #include "lisp.h" #include "blockinput.h" - -/* Need syssignal.h for various externs and definitions that may be required - by some configurations for calls to signal later in this source file. */ #include "syssignal.h" /* This may include sys/types.h, and that somehow loses @@ -7766,7 +7762,9 @@ #ifdef USG /* USG systems forget handlers when they are used; must reestablish each time */ - signal (signalnum, x_connection_signal); + struct sigaction action; + emacs_sigaction_init (&action, x_connection_signal); + sigaction (signalnum, &action, 0); #endif /* USG */ } @@ -7788,6 +7786,7 @@ struct x_display_info *dpyinfo = x_display_info_for_display (dpy); Lisp_Object frame, tail; ptrdiff_t idx = SPECPDL_INDEX (); + sigset_t unblocked; error_msg = alloca (strlen (error_message) + 1); strcpy (error_msg, error_message); @@ -7876,10 +7875,12 @@ } /* Ordinary stack unwind doesn't deal with these. */ + sigemptyset (&unblocked); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + sigaddset (&unblocked, SIGIO); #endif - sigunblock (sigmask (SIGALRM)); + sigaddset (&unblocked, SIGALRM); + pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); TOTALLY_UNBLOCK_INPUT; unbind_to (idx, Qnil); @@ -10759,6 +10760,8 @@ void x_initialize (void) { + struct sigaction action; + baud_rate = 19200; x_noop_count = 0; @@ -10805,7 +10808,8 @@ XSetErrorHandler (x_error_handler); XSetIOErrorHandler (x_io_error_quitter); - signal (SIGPIPE, x_connection_signal); + emacs_sigaction_init (&action, x_connection_signal); + sigaction (SIGPIPE, &action, 0); }