From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#12327: Signal-handler cleanup for Emacs Date: Sat, 01 Sep 2012 15:38:15 -0700 Organization: UCLA Computer Science Department Message-ID: <50428E57.8070708@cs.ucla.edu> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1346539192 23078 80.91.229.3 (1 Sep 2012 22:39:52 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 1 Sep 2012 22:39:52 +0000 (UTC) Cc: Juanma Barranquero To: 12327@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Sep 02 00:39:52 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1T7wM3-0006ih-U1 for geb-bug-gnu-emacs@m.gmane.org; Sun, 02 Sep 2012 00:39:52 +0200 Original-Received: from localhost ([::1]:52945 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wM0-0000KI-TP for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Sep 2012 18:39:48 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:55796) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wLv-0000K4-3x for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:39:47 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T7wLr-00077O-8q for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:39:43 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:52024) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wLr-00077K-3d for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:39:39 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1T7wNC-00037T-6i for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:41:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 01 Sep 2012 22:41:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 12327 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.134653920811931 (code B ref -1); Sat, 01 Sep 2012 22:41:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 1 Sep 2012 22:40:08 +0000 Original-Received: from localhost ([127.0.0.1]:33337 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1T7wMC-00035s-1v for submit@debbugs.gnu.org; Sat, 01 Sep 2012 18:40:07 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:38275) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1T7wM5-00035i-Us for submit@debbugs.gnu.org; Sat, 01 Sep 2012 18:39:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T7wKg-0006th-E2 for submit@debbugs.gnu.org; Sat, 01 Sep 2012 18:38:30 -0400 Original-Received: from lists.gnu.org ([208.118.235.17]:34285) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wKg-0006td-9j for submit@debbugs.gnu.org; Sat, 01 Sep 2012 18:38:26 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:55640) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wKc-0000Cs-AT for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:38:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T7wKX-0006so-QZ for bug-gnu-emacs@gnu.org; Sat, 01 Sep 2012 18:38:22 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]:39786) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T7wKX-0006sd-5q; Sat, 01 Sep 2012 18:38:17 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 9FB75A60006; Sat, 1 Sep 2012 15:38:16 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1m893B89r+LV; Sat, 1 Sep 2012 15:38:13 -0700 (PDT) Original-Received: from [192.168.1.3] (pool-108-23-119-2.lsanca.fios.verizon.net [108.23.119.2]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id C5F4AA6000D; Sat, 1 Sep 2012 15:38:12 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20120827 Thunderbird/15.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:63657 Archived-At: Tags: patch Here's a patch to clean up Emacs's signal-handling code somewhat. As described below, it shrinks the size of Emacs's text segment by 0.6% on my platform. It also removes a few dozen lines from the source code. This patch affects only the mainline code. Some tweaks will be needed to the Windows port, which will need to define the functions 'sighandler' and 'set_sighandler'; these are specialized replacements for 'sys_signal' that avoid the overhead of setting/getting when it's not needed. I'm planning to install this into the trunk and am publishing it now as a head-up for the Windows side. === modified file 'ChangeLog' --- ChangeLog 2012-09-01 18:54:38 +0000 +++ ChangeLog 2012-09-01 21:51:42 +0000 @@ -1,5 +1,10 @@ 2012-09-01 Paul Eggert + Signal-handler cleanup. + * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF): + Adjust to syssignal.h changes. + (SIGNAL_H_AB): Remove; no longer needed. + * configure.ac (_FORTIFY_SOURCE): Define only when optimizing. This ports to glibc 2.15 or later, when configured with --enable-gcc-warnings. See Eric Blake in === modified file 'configure.ac' --- configure.ac 2012-09-01 18:54:38 +0000 +++ configure.ac 2012-09-01 21:37:48 +0000 @@ -3445,7 +3445,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 mask; get_sigmask_block_signal (SIGCHLD, &mask); if (-1 == openpty (&fd, &dummy, pty_name, 0, 0)) fd = -1; set_signal_mask (&mask); if (fd >= 0) emacs_close (dummy); } while (0)]) AC_DEFINE(PTY_NAME_SPRINTF, []) AC_DEFINE(PTY_TTY_NAME_SPRINTF, []) ;; @@ -3474,7 +3474,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; block_signal (SIGCHLD); if (grantpt (fd) == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname(fd))) { unblock_signal (SIGCHLD); close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); unblock_signal (SIGCHLD); }]) 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)]) @@ -3525,12 +3525,12 @@ 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; block_signal (SIGCLD); if (grantpt (fd) == -1) { emacs_close (fd); return -1; } unblock_signal (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); }]) ;; 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; block_signal (SIGCLD); if (grantpt(fd) == -1) fatal("could not grant slave pty"); unblock_signal (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); }]) ;; esac @@ -3806,13 +3806,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-01 13:54:27 +0000 +++ src/ChangeLog 2012-09-01 21:50:12 +0000 @@ -1,3 +1,66 @@ +2012-09-01 Paul Eggert + + Signal-handler cleanup. + 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.6% 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. + * callproc.c (Fcall_process) [HAVE_WORKING_VFORK]: + Use new get_sigmask_block_signal and set_sigmask functions instead + of repeating the code inline. + * conf_post.h [SIGNAL_H_AHB]: Do not include ; + no longer needed here. + * emacs.c (main): Use new sighandler function, so that there's + no need to block and unblock SIGHUP. + * sysdep.c (SYSSIGNAL_INLINE): New macro. + (empty_mask): Remove. All uses replaced to create their own + masks, as this avoids static storage and offers the compiler more + optimization opportunities. + (sighandler, get_set_sighandler, set_sighandler) [!WINDOWSNT]: + New functions. All users of 'signal' modified to use sighandler + if they're readonly, to set_sighandler if they're writeonly, and to + sys_signal if they're read+write. + (sys_signal): Reimplement in terms of get_set_sighandler. + (sys_sigmask) [!__GNUC__]: Remove; no longer needed. + (sys_sigblock): Remove; replaced by block_signal and + get_sigmask_block_signal. All uses changed. + (sys_sigunblock): Remove; replaced by unblock_signal. All uses changed. + (sys_sigsetmask): Remove; replaced by set_sigmask. All uses changed. + * syssignal.h: Include , since we need its types, + and since we need bool. + (SIGMASKTYPE): Remove. All uses replaced by its definiens, sigset_t. + (SIGEMPTYMASK, empty_mask): Remove as described above. + (sigmask, sys_sigmask): Remove; no longer needed. + (sigpause): Remove. All uses replaced by its definiens, sigsuspend. + (sigblock): Remove. All uses replaced by block_signal. + (sigunblock): Remove. All uses replaced by unblock_signal. + (sigsetmask) [!defined sigsetmask]: Remove. All uses replaced by + set_sigmask. + (signal): Remove. All uses replaced by sighandler, set_sighandler, + or sys_signal as described above. + (init_signals): Now ATTRIBUTE_CONST in the usual case. + (get_sigmask_block_signal, block_signal, unblock_signal, set_sigmask): + New functions. + (sigfree): Reimplement in terms of set_sigmask. + (sighandler, set_sighandler): New decls. + (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove decls. + (sys_sigdel): Remove; unused. + (NSIG): Remove a FIXME; the code's fine. Remove an unnecessary ifdef. + (forwarded_signal): Rename from SIGNAL_THREAD_CHECK, and turn into + a boolean function. This is cleaner, because the caller can now + see that the check might immediately return from the caller. + All uses changed. + 2012-09-01 Eli Zaretskii * w32uniscribe.c (uniscribe_shape): Handle correctly the case of === modified file 'src/alloc.c' --- src/alloc.c 2012-08-31 10:53:19 +0000 +++ src/alloc.c 2012-09-01 21:37:07 +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-01 21:37:07 +0000 @@ -17,7 +17,6 @@ along with GNU Emacs. If not, see . */ #include -#include #include #include #include "lisp.h" @@ -51,8 +50,8 @@ /* Block/unblock SIGALRM. */ -#define BLOCK_ATIMERS sigblock (sigmask (SIGALRM)) -#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM)) +#define BLOCK_ATIMERS block_signal (SIGALRM) +#define UNBLOCK_ATIMERS unblock_signal (SIGALRM) /* Function prototypes. */ @@ -378,7 +377,8 @@ alarm_signal_handler (int signo) { #ifndef SYNC_INPUT - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; #endif pending_atimers = 1; @@ -412,7 +412,7 @@ { if (on) { - signal (SIGALRM, alarm_signal_handler); + set_sighandler (SIGALRM, alarm_signal_handler); set_alarm (); } else @@ -426,5 +426,5 @@ free_atimers = stopped_atimers = atimers = NULL; pending_atimers = 0; /* pending_signals is initialized in init_keyboard.*/ - signal (SIGALRM, alarm_signal_handler); + set_sighandler (SIGALRM, alarm_signal_handler); } === modified file 'src/callproc.c' --- src/callproc.c 2012-08-25 03:11:12 +0000 +++ src/callproc.c 2012-09-01 21:37:07 +0000 @@ -19,7 +19,6 @@ #include -#include #include #include #include @@ -500,15 +499,11 @@ int fd_error = fd1; #ifdef HAVE_WORKING_VFORK sigset_t procmask; - sigset_t blocked; struct sigaction sigpipe_action; #endif 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; @@ -597,10 +592,8 @@ this sets the parent's signal handlers as well as the child's. So delay all interrupts whose handlers the child might munge, and record the current handlers so they can be restored later. */ - sigemptyset (&blocked); - sigaddset (&blocked, SIGPIPE); sigaction (SIGPIPE, 0, &sigpipe_action); - pthread_sigmask (SIG_BLOCK, &blocked, &procmask); + get_sigmask_block_signal (&procmask, SIGPIPE); #endif BLOCK_INPUT; @@ -649,9 +642,9 @@ /* GConf causes us to ignore SIGPIPE, make sure it is restored in the child. */ - signal (SIGPIPE, SIG_DFL); + set_sighandler (SIGPIPE, SIG_DFL); #ifdef HAVE_WORKING_VFORK - pthread_sigmask (SIG_SETMASK, &procmask, 0); + set_sigmask (&procmask); #endif child_setup (filefd, fd1, fd_error, (char **) new_argv, @@ -663,7 +656,7 @@ #ifdef HAVE_WORKING_VFORK /* Restore the signal state. */ sigaction (SIGPIPE, &sigpipe_action, 0); - pthread_sigmask (SIG_SETMASK, &procmask, 0); + set_sigmask (&procmask); #endif #endif /* not WINDOWSNT */ === 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-01 21:37:07 +0000 @@ -19,7 +19,6 @@ #include -#include #include #include @@ -3213,9 +3212,9 @@ static void arith_error (int signo) { - sigsetmask (SIGEMPTYMASK); - - SIGNAL_THREAD_CHECK (signo); + sigfree (); + if (forwarded_signal (signo)) + return; xsignal0 (Qarith_error); } @@ -3230,5 +3229,5 @@ if (!initialized) return; #endif /* CANNOT_DUMP */ - signal (SIGFPE, arith_error); + set_sighandler (SIGFPE, arith_error); } === modified file 'src/dispnew.c' --- src/dispnew.c 2012-09-01 06:38:52 +0000 +++ src/dispnew.c 2012-09-01 21:37:07 +0000 @@ -21,7 +21,6 @@ #define DISPEXTERN_INLINE EXTERN_INLINE -#include #include #include #include @@ -5561,8 +5560,9 @@ struct tty_display_info *tty; - signal (SIGWINCH, window_change_signal); - SIGNAL_THREAD_CHECK (signalnum); + set_sighandler (SIGWINCH, window_change_signal); + 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 +6173,7 @@ #ifndef CANNOT_DUMP if (initialized) #endif /* CANNOT_DUMP */ - signal (SIGWINCH, window_change_signal); + set_sighandler (SIGWINCH, window_change_signal); #endif /* SIGWINCH */ /* If running as a daemon, no need to initialize any frames/terminal. */ === modified file 'src/emacs.c' --- src/emacs.c 2012-09-01 08:01:36 +0000 +++ src/emacs.c 2012-09-01 21:37:07 +0000 @@ -20,7 +20,6 @@ #include -#include #include #include @@ -297,9 +296,10 @@ void fatal_error_signal (int sig) { - SIGNAL_THREAD_CHECK (sig); + if (forwarded_signal (sig)) + return; fatal_error_code = sig; - signal (sig, SIG_DFL); + set_sighandler (sig, SIG_DFL); TOTALLY_UNBLOCK_INPUT; @@ -319,7 +319,7 @@ 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)); + unblock_signal (fatal_error_code); #endif kill (getpid (), fatal_error_code); @@ -331,8 +331,9 @@ void memory_warning_signal (int sig) { - signal (sig, memory_warning_signal); - SIGNAL_THREAD_CHECK (sig); + set_sighandler (sig, memory_warning_signal); + if (forwarded_signal (sig)) + return; malloc_warning ("Operating system warns that virtual memory is running low.\n"); @@ -1119,13 +1120,10 @@ #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)); + if (! (noninteractive && sighandler (SIGHUP) == SIG_IGN)) + set_sighandler (SIGHUP, fatal_error_signal); } if ( @@ -1139,9 +1137,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); + set_sighandler (SIGQUIT, fatal_error_signal); + set_sighandler (SIGILL, fatal_error_signal); + set_sighandler (SIGTRAP, fatal_error_signal); #ifdef SIGUSR1 add_user_signal (SIGUSR1, "sigusr1"); #endif @@ -1149,68 +1147,69 @@ add_user_signal (SIGUSR2, "sigusr2"); #endif #ifdef SIGABRT - signal (SIGABRT, fatal_error_signal); + set_sighandler (SIGABRT, fatal_error_signal); #endif #ifdef SIGHWE - signal (SIGHWE, fatal_error_signal); + set_sighandler (SIGHWE, fatal_error_signal); #endif #ifdef SIGPRE - signal (SIGPRE, fatal_error_signal); + set_sighandler (SIGPRE, fatal_error_signal); #endif #ifdef SIGORE - signal (SIGORE, fatal_error_signal); + set_sighandler (SIGORE, fatal_error_signal); #endif #ifdef SIGUME - signal (SIGUME, fatal_error_signal); + set_sighandler (SIGUME, fatal_error_signal); #endif #ifdef SIGDLK - signal (SIGDLK, fatal_error_signal); + set_sighandler (SIGDLK, fatal_error_signal); #endif #ifdef SIGCPULIM - signal (SIGCPULIM, fatal_error_signal); + set_sighandler (SIGCPULIM, fatal_error_signal); #endif #ifdef SIGIOT /* This is missing on some systems - OS/2, for example. */ - signal (SIGIOT, fatal_error_signal); + set_sighandler (SIGIOT, fatal_error_signal); #endif #ifdef SIGEMT - signal (SIGEMT, fatal_error_signal); + set_sighandler (SIGEMT, fatal_error_signal); #endif - signal (SIGFPE, fatal_error_signal); + set_sighandler (SIGFPE, fatal_error_signal); #ifdef SIGBUS - signal (SIGBUS, fatal_error_signal); + set_sighandler (SIGBUS, fatal_error_signal); #endif - signal (SIGSEGV, fatal_error_signal); + set_sighandler (SIGSEGV, fatal_error_signal); #ifdef SIGSYS - signal (SIGSYS, fatal_error_signal); + set_sighandler (SIGSYS, fatal_error_signal); #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) + set_sighandler (SIGINT, fatal_error_signal); + set_sighandler (SIGTERM, fatal_error_signal); #ifdef SIGXCPU - signal (SIGXCPU, fatal_error_signal); + set_sighandler (SIGXCPU, fatal_error_signal); #endif #ifdef SIGXFSZ - signal (SIGXFSZ, fatal_error_signal); + set_sighandler (SIGXFSZ, fatal_error_signal); #endif /* SIGXFSZ */ #ifdef SIGDANGER /* This just means available memory is getting low. */ - signal (SIGDANGER, memory_warning_signal); + set_sighandler (SIGDANGER, memory_warning_signal); #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); + set_sighandler (SIGXCPU, fatal_error_signal); + set_sighandler (SIGIOINT, fatal_error_signal); + set_sighandler (SIGGRANT, fatal_error_signal); + set_sighandler (SIGRETRACT, fatal_error_signal); + set_sighandler (SIGSOUND, fatal_error_signal); + set_sighandler (SIGMSG, fatal_error_signal); #endif /* AIX */ } @@ -2041,7 +2040,7 @@ /* There is a tendency for a SIGIO signal to arrive within exit, and cause a SIGHUP because the input descriptor is already closed. */ unrequest_sigio (); - signal (SIGIO, SIG_IGN); + set_sighandler (SIGIO, SIG_IGN); #endif #ifdef WINDOWSNT === 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-01 21:37:07 +0000 @@ -48,7 +48,6 @@ */ #include -#include #include #include "lisp.h" #include "syssignal.h" @@ -955,13 +954,14 @@ fatal_error_signal (signo); #ifdef BSD_SYSTEM - sigsetmask (SIGEMPTYMASK); + sigfree (); #else /* Must reestablish handler each time it is called. */ - signal (SIGILL, float_error); + set_sighandler (SIGILL, float_error); #endif /* BSD_SYSTEM */ - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; in_float = 0; xsignal1 (Qarith_error, float_error_arg); @@ -1007,7 +1007,7 @@ init_floatfns (void) { #ifdef FLOAT_CATCH_SIGILL - signal (SIGILL, float_error); + set_sighandler (SIGILL, float_error); #endif in_float = 0; } === modified file 'src/gtkutil.c' --- src/gtkutil.c 2012-08-30 16:07:44 +0000 +++ src/gtkutil.c 2012-09-01 21:37:07 +0000 @@ -21,7 +21,6 @@ #ifdef USE_GTK #include -#include #include #include @@ -1979,7 +1978,7 @@ /* 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)); + block_signal (__SIGRTMIN); #endif /* HAVE_PTHREAD */ #ifdef HAVE_GTK_FILE_SELECTION_NEW @@ -2001,7 +2000,7 @@ filesel_done = xg_dialog_run (f, w); #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigunblock (sigmask (__SIGRTMIN)); + unblock_signal (__SIGRTMIN); #endif if (filesel_done == GTK_RESPONSE_OK) @@ -2061,7 +2060,7 @@ Lisp_Object font = Qnil; #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigblock (sigmask (__SIGRTMIN)); + block_signal (__SIGRTMIN); #endif /* HAVE_PTHREAD */ w = gtk_font_chooser_dialog_new @@ -2090,7 +2089,7 @@ done = xg_dialog_run (f, w); #if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) - sigunblock (sigmask (__SIGRTMIN)); + unblock_signal (__SIGRTMIN); #endif if (done == GTK_RESPONSE_OK) === modified file 'src/keyboard.c' --- src/keyboard.c 2012-09-01 06:38:52 +0000 +++ src/keyboard.c 2012-09-01 21:37:07 +0000 @@ -21,7 +21,6 @@ #define KEYBOARD_INLINE EXTERN_INLINE -#include #include #include #include "lisp.h" @@ -3661,7 +3660,7 @@ hold_keyboard_input (); #ifdef SIGIO if (!noninteractive) - signal (SIGIO, SIG_IGN); + set_sighandler (SIGIO, SIG_IGN); #endif stop_polling (); } @@ -3833,7 +3832,7 @@ unhold_keyboard_input (); #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + set_sighandler (SIGIO, input_available_signal); #endif /* SIGIO */ start_polling (); } @@ -6782,10 +6781,10 @@ #ifdef SIGIO if (interrupt_input) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGIO)); + sigset_t mask; + get_sigmask_block_signal (&mask, SIGIO); read_avail_input (expected); - sigsetmask (mask); + set_sigmask (&mask); } else #ifdef POLL_FOR_INPUT @@ -6794,10 +6793,10 @@ it's always set. */ if (!interrupt_input && poll_suppress_count == 0) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGALRM)); + sigset_t mask; + get_sigmask_block_signal (&mask, SIGALRM); read_avail_input (expected); - sigsetmask (mask); + set_sigmask (&mask); } else #endif @@ -6833,10 +6832,10 @@ #ifdef SIGIO if (interrupt_input) { - SIGMASKTYPE mask; - mask = sigblock (sigmask (SIGIO)); + sigset_t mask; + get_sigmask_block_signal (&mask, SIGIO); kbd_buffer_store_event (&event); - sigsetmask (mask); + set_sigmask (&mask); } else #endif @@ -7241,7 +7240,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; @@ -7311,7 +7311,7 @@ p->next = user_signals; user_signals = p; - signal (sig, handle_user_signal); + set_sighandler (sig, handle_user_signal); } static void @@ -7321,7 +7321,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)); @@ -7382,7 +7383,7 @@ for (p = user_signals; p; p = p->next) if (p->npending > 0) { - SIGMASKTYPE mask; + sigset_t mask; if (nstored == 0) { @@ -7392,7 +7393,7 @@ } nstored += p->npending; - mask = sigblock (sigmask (p->sig)); + get_sigmask_block_signal (&mask, p->sig); do { buf.code = p->sig; @@ -7400,7 +7401,7 @@ p->npending--; } while (p->npending > 0); - sigsetmask (mask); + set_sigmask (&mask); } return nstored; @@ -8445,7 +8446,7 @@ /* Append entries from tool_bar_item_properties to the end of tool_bar_items_vector. */ - vcopy (tool_bar_items_vector, ntool_bar_items, + vcopy (tool_bar_items_vector, ntool_bar_items, XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS); ntool_bar_items += TOOL_BAR_ITEM_NSLOTS; } @@ -10784,7 +10785,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"); @@ -10841,7 +10843,7 @@ /* 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)); + block_signal (SIGINT); fflush (stdout); reset_all_sys_modes (); @@ -11405,17 +11407,17 @@ 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); + set_sighandler (SIGINT, interrupt_signal); #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); + set_sighandler (SIGQUIT, interrupt_signal); #endif /* not DOS_NT */ } /* Note SIGIO has been undef'd if FIONREAD is missing. */ #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + set_sighandler (SIGIO, input_available_signal); #endif /* SIGIO */ /* Use interrupt input by default, if it works and noninterrupt input === 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-01 06:38:52 +0000 +++ src/process.c 2012-09-01 21:37:07 +0000 @@ -23,7 +23,6 @@ #define PROCESS_INLINE EXTERN_INLINE -#include #include #include #include @@ -1766,12 +1765,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. */ @@ -1880,18 +1873,18 @@ /* On AIX, we've disabled SIGHUP above once we start a child on a pty. Now reenable it in the child, so it will die when we want it to. */ if (pty_flag) - signal (SIGHUP, SIG_DFL); + set_sighandler (SIGHUP, SIG_DFL); #endif #endif /* HAVE_PTYS */ - signal (SIGINT, SIG_DFL); - signal (SIGQUIT, SIG_DFL); + set_sighandler (SIGINT, SIG_DFL); + set_sighandler (SIGQUIT, SIG_DFL); /* GConf causes us to ignore SIGPIPE, make sure it is restored in the child. */ - signal (SIGPIPE, SIG_DFL); + set_sighandler (SIGPIPE, SIG_DFL); /* Stop blocking signals in the child. */ - pthread_sigmask (SIG_SETMASK, &procmask, 0); + set_sigmask (&procmask); if (pty_flag) child_setup_tty (xforkout); @@ -1982,7 +1975,7 @@ #endif #endif /* HAVE_WORKING_VFORK */ /* Stop blocking signals in the parent. */ - pthread_sigmask (SIG_SETMASK, &procmask, 0); + set_sigmask (&procmask); /* Now generate the error if vfork failed. */ if (pid < 0) @@ -5439,8 +5432,9 @@ static void send_process_trap (int ignore) { - SIGNAL_THREAD_CHECK (SIGPIPE); - sigunblock (sigmask (SIGPIPE)); + if (forwarded_signal (SIGPIPE)) + return; + unblock_signal (SIGPIPE); longjmp (send_process_frame, 1); } @@ -5534,7 +5528,7 @@ struct Lisp_Process *p = XPROCESS (proc); ssize_t rv; struct coding_system *coding; - void (*volatile old_sigpipe) (int); + signal_handler_t volatile old_sigpipe; if (p->raw_status_new) update_status (p); @@ -5673,7 +5667,7 @@ /* 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); + old_sigpipe = sys_signal (SIGPIPE, send_process_trap); #ifdef DATAGRAM_SOCKETS if (DATAGRAM_CHAN_P (outfd)) { @@ -5684,7 +5678,7 @@ written = rv; else if (errno == EMSGSIZE) { - signal (SIGPIPE, old_sigpipe); + set_sighandler (SIGPIPE, old_sigpipe); report_file_error ("sending datagram", Fcons (proc, Qnil)); } @@ -5709,7 +5703,7 @@ } #endif } - signal (SIGPIPE, old_sigpipe); + set_sighandler (SIGPIPE, old_sigpipe); if (rv < 0) { @@ -5769,7 +5763,7 @@ } else { - signal (SIGPIPE, old_sigpipe); + set_sighandler (SIGPIPE, old_sigpipe); proc = process_sent_to; p = XPROCESS (proc); p->raw_status_new = 0; @@ -6414,7 +6408,8 @@ Lisp_Object proc; struct Lisp_Process *p; - SIGNAL_THREAD_CHECK (signo); + if (forwarded_signal (signo)) + return; while (1) { @@ -7397,7 +7392,7 @@ #ifndef CANNOT_DUMP if (! noninteractive || initialized) #endif - signal (SIGCHLD, sigchld_handler); + set_sighandler (SIGCHLD, sigchld_handler); #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-01 21:37:07 +0000 @@ -48,7 +48,6 @@ #include "lisp.h" #include "dispextern.h" #include "atimer.h" -#include #include "syssignal.h" /* END: Common Includes */ @@ -316,7 +315,7 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + unblock_signal (SIGIO); #endif if (saved_errno != 0) error ("%s: %s", msg, strerror (saved_errno)); @@ -736,7 +735,7 @@ troubles. */ turn_on_atimers (0); #ifdef SIGIO - sigblock (sigmask (SIGIO)); + block_signal (SIGIO); #endif val = sd->format; @@ -770,7 +769,7 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + unblock_signal (SIGIO); #endif } @@ -786,7 +785,7 @@ be interrupted by a signal. Block the ones we know to cause troubles. */ #ifdef SIGIO - sigblock (sigmask (SIGIO)); + block_signal (SIGIO); #endif turn_on_atimers (0); @@ -795,7 +794,7 @@ turn_on_atimers (1); #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + unblock_signal (SIGIO); #endif /* Close the device. */ === modified file 'src/sysdep.c' --- src/sysdep.c 2012-09-01 01:13:50 +0000 +++ src/sysdep.c 2012-09-01 21:37:07 +0000 @@ -19,9 +19,9 @@ #include +#define SYSSIGNAL_INLINE EXTERN_INLINE #define SYSTIME_INLINE EXTERN_INLINE -#include #include #include #ifdef HAVE_PWD_H @@ -302,31 +302,43 @@ 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); + set_sigmask (&sigchild_mask); + if (0 > kill (pid, 0)) { - sigsetmask (SIGEMPTYMASK); + sigfree (); kill (getpid (), SIGCHLD); break; } if (wait_debugging) sleep (1); else - sigpause (SIGEMPTYMASK); + { + sigset_t empty_mask; + sigemptyset (&empty_mask); + sigsuspend (&empty_mask); + } #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ #ifdef WINDOWSNT wait (0); break; #else /* not WINDOWSNT */ - sigblock (sigmask (SIGCHLD)); + block_signal (SIGCHLD); errno = 0; if (kill (pid, 0) == -1 && errno == ESRCH) { - sigunblock (sigmask (SIGCHLD)); + unblock_signal (SIGCHLD); break; } - sigsuspend (&empty_mask); + { + sigset_t empty_mask; + sigemptyset (&empty_mask); + sigsuspend (&empty_mask); + } #endif /* not WINDOWSNT */ #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */ if (interruptible) @@ -460,7 +472,7 @@ struct save_signal { int code; - void (*handler) (int); + signal_handler_t handler; }; static void save_signal_handlers (struct save_signal *); @@ -618,8 +630,7 @@ { while (saved_handlers->code) { - saved_handlers->handler - = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); + saved_handlers->handler = sys_signal (saved_handlers->code, SIG_IGN); saved_handlers++; } } @@ -629,7 +640,7 @@ { while (saved_handlers->code) { - signal (saved_handlers->code, saved_handlers->handler); + set_sighandler (saved_handlers->code, saved_handlers->handler); saved_handlers++; } } @@ -690,9 +701,9 @@ return; #ifdef SIGWINCH - sigunblock (sigmask (SIGWINCH)); + unblock_signal (SIGWINCH); #endif - sigunblock (sigmask (SIGIO)); + unblock_signal (SIGIO); interrupts_deferred = 0; } @@ -709,9 +720,9 @@ #endif #ifdef SIGWINCH - sigblock (sigmask (SIGWINCH)); + block_signal (SIGWINCH); #endif - sigblock (sigmask (SIGIO)); + block_signal (SIGIO); interrupts_deferred = 1; } @@ -1473,16 +1484,27 @@ /* POSIX signals support - DJB */ /* Anyone with POSIX signals should have ANSI C declarations */ -sigset_t empty_mask; - #ifndef WINDOWSNT +/* Return the current signal handler for signal number SIGNO. */ signal_handler_t -sys_signal (int signal_number, signal_handler_t action) -{ - struct sigaction new_action, old_action; +sighandler (int signo) +{ + struct sigaction old_action; + sigaction (signo, NULL, &old_action); + return old_action.sa_handler; +} + +/* Copy the old signal action for SIGNO into *OLD_ACTION if OLD_ACTION + is non-null. Then change the signal action to be one whose handler + is HANDLER. */ +static void +get_set_sighandler (int signo, struct sigaction *old_action, + signal_handler_t handler) +{ + struct sigaction new_action; sigemptyset (&new_action.sa_mask); - new_action.sa_handler = action; + new_action.sa_handler = handler; new_action.sa_flags = 0; #if defined (SA_RESTART) /* Emacs mostly works better with restartable system services. If this @@ -1502,54 +1524,26 @@ # endif new_action.sa_flags = SA_RESTART; #endif - sigaction (signal_number, &new_action, &old_action); - return (old_action.sa_handler); + sigaction (signo, &new_action, old_action); +} + +/* Change SIGNO's handler to be HANDLER. */ +void +set_sighandler (int signo, signal_handler_t handler) +{ + get_set_sighandler (signo, NULL, handler); +} + +/* Change SIGNO's handler to be HANDLER. Return the old handler. */ +signal_handler_t +sys_signal (int signo, signal_handler_t handler) +{ + struct sigaction old_action; + get_set_sighandler (signo, &old_action, handler); + 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); -} - #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST static char *my_sys_siglist[NSIG]; @@ -1562,8 +1556,6 @@ void init_signals (void) { - sigemptyset (&empty_mask); - #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST if (! initialized) { === modified file 'src/syssignal.h' --- src/syssignal.h 2012-07-13 01:19:06 +0000 +++ src/syssignal.h 2012-09-01 21:37:07 +0000 @@ -17,7 +17,8 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ -extern void init_signals (void); +#include +#include #ifdef HAVE_PTHREAD #include @@ -26,63 +27,65 @@ #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) -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. */ +INLINE_HEADER_BEGIN +#ifndef SYSSIGNAL_INLINE +# define SYSSIGNAL_INLINE INLINE +#endif + +extern void init_signals (void) +#if defined HAVE_STRSIGNAL || HAVE_DECL_SYS_SIGLIST + ATTRIBUTE_CONST +#endif + ; + +SYSSIGNAL_INLINE void +get_sigmask_block_signal (sigset_t *old_mask, int sig) +{ + sigset_t mask; + sigemptyset (&mask); + sigaddset (&mask, sig); + pthread_sigmask (SIG_BLOCK, &mask, old_mask); +} + +SYSSIGNAL_INLINE void +block_signal (int sig) +{ + get_sigmask_block_signal (NULL, sig); +} + +SYSSIGNAL_INLINE void +unblock_signal (int sig) +{ + sigset_t mask; + sigemptyset (&mask); + sigaddset (&mask, sig); + pthread_sigmask (SIG_UNBLOCK, &mask, NULL); +} + +SYSSIGNAL_INLINE void +set_sigmask (sigset_t *mask) +{ + pthread_sigmask (SIG_SETMASK, mask, NULL); +} + +SYSSIGNAL_INLINE void +sigfree (void) +{ + sigset_t empty_mask; + sigemptyset (&empty_mask); + set_sigmask (&empty_mask); +} + 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); +signal_handler_t sighandler (int); +void set_sighandler (int, signal_handler_t); +signal_handler_t sys_signal (int, 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 +100,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 +132,20 @@ #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) - -#else /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ -#define SIGNAL_THREAD_CHECK(signo) -#endif /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ +#endif + +SYSSIGNAL_INLINE bool +forwarded_signal (int signo) +{ +#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD + if (! pthread_equal (pthread_self (), main_thread)) + { + block_signal (signo); + pthread_kill (main_thread, signo); + return 1; + } +#endif + return 0; +} + +INLINE_HEADER_END === modified file 'src/term.c' --- src/term.c 2012-08-31 10:53:19 +0000 +++ src/term.c 2012-09-01 21:37:07 +0000 @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "lisp.h" @@ -2932,7 +2931,7 @@ no_controlling_tty = 1; #else #ifdef TIOCNOTTY /* Try BSD ioctls. */ - sigblock (sigmask (SIGTTOU)); + block_signal (SIGTTOU); fd = emacs_open (DEV_TTY, O_RDWR, 0); if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1) { @@ -2940,7 +2939,7 @@ } if (fd != -1) emacs_close (fd); - sigunblock (sigmask (SIGTTOU)); + unblock_signal (SIGTTOU); #else /* Unknown system. */ croak (); @@ -3074,9 +3073,9 @@ /* On some systems, tgetent tries to access the controlling terminal. */ - sigblock (sigmask (SIGTTOU)); + block_signal (SIGTTOU); status = tgetent (tty->termcap_term_buffer, terminal_type); - sigunblock (sigmask (SIGTTOU)); + unblock_signal (SIGTTOU); if (status < 0) { === modified file 'src/widget.c' --- src/widget.c 2012-07-10 21:48:34 +0000 +++ src/widget.c 2012-09-01 21:37:07 +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-08-25 20:31:04 +0000 +++ src/xterm.c 2012-09-01 21:37:07 +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 @@ -7773,7 +7769,7 @@ #ifdef USG /* USG systems forget handlers when they are used; must reestablish each time */ - signal (signalnum, x_connection_signal); + set_sighandler (signalnum, x_connection_signal); #endif /* USG */ } @@ -7884,9 +7880,9 @@ /* Ordinary stack unwind doesn't deal with these. */ #ifdef SIGIO - sigunblock (sigmask (SIGIO)); + unblock_signal (SIGIO); #endif - sigunblock (sigmask (SIGALRM)); + unblock_signal (SIGALRM); TOTALLY_UNBLOCK_INPUT; unbind_to (idx, Qnil); @@ -10814,7 +10810,7 @@ XSetErrorHandler (x_error_handler); XSetIOErrorHandler (x_io_error_quitter); - signal (SIGPIPE, x_connection_signal); + set_sighandler (SIGPIPE, x_connection_signal); }