diff options
| author | Paul Eggert | 2012-09-06 18:27:44 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-09-06 18:27:44 -0700 |
| commit | 2fe282993cf9c84f5be424dc93d03f9705a7edd8 (patch) | |
| tree | 229edb6fe29e66984b2992f3f9fa081cd7fe8920 /src/process.c | |
| parent | 845ce106c0ab157e25416964330875ad6c24b699 (diff) | |
| download | emacs-2fe282993cf9c84f5be424dc93d03f9705a7edd8.tar.gz emacs-2fe282993cf9c84f5be424dc93d03f9705a7edd8.zip | |
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.7% on my platform, Fedora 17 x86-64.
* configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF):
Adjust to syssignal.h changes.
(SIGNAL_H_AB): Remove; no longer needed.
* src/alloc.c, src/emacsgtkfixed.c, src/nsfns.m, src/widget.c, src/xmenu.c:
Do not include <signal.h> or "syssignal.h", as these
modules do not use signals.
* src/atimer.c, src/callproc.c, src/data.c, src/dispnew.c, src/emacs.c:
* src/floatfns.c, src/gtkutil.c, src/keyboard.c, src/process.c, src/sound.c:
* src/sysdep.c, src/term.c, src/xterm.c:
Do not include <signal.h>, as "syssignal.h" does that for us now.
* src/atimer.c (sigmask_atimers): New function.
(block_atimers, unblock_atimers): New functions,
replacing the old macros BLOCK_ATIMERS and UNBLOCK_ATIMERS.
All uses replaced.
* src/conf_post.h [SIGNAL_H_AHB]: Do not include <signal.h>;
no longer needed here.
* src/emacs.c (main): Inspect existing signal handler with sigaction,
so that there's no need to block and unblock SIGHUP.
* src/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.
* src/syssignal.h: Include <signal.h>.
(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.
Fixes: debbugs:12327
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/src/process.c b/src/process.c index 9ab8d2720b2..0cc9bc353a1 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 23 | 23 | ||
| 24 | #define PROCESS_INLINE EXTERN_INLINE | 24 | #define PROCESS_INLINE EXTERN_INLINE |
| 25 | 25 | ||
| 26 | #include <signal.h> | ||
| 27 | #include <stdio.h> | 26 | #include <stdio.h> |
| 28 | #include <errno.h> | 27 | #include <errno.h> |
| 29 | #include <setjmp.h> | 28 | #include <setjmp.h> |
| @@ -1612,8 +1611,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1612 | #if !defined (WINDOWSNT) && defined (FD_CLOEXEC) | 1611 | #if !defined (WINDOWSNT) && defined (FD_CLOEXEC) |
| 1613 | int wait_child_setup[2]; | 1612 | int wait_child_setup[2]; |
| 1614 | #endif | 1613 | #endif |
| 1615 | sigset_t procmask; | 1614 | sigset_t blocked, procmask; |
| 1616 | sigset_t blocked; | ||
| 1617 | struct sigaction sigint_action; | 1615 | struct sigaction sigint_action; |
| 1618 | struct sigaction sigquit_action; | 1616 | struct sigaction sigquit_action; |
| 1619 | struct sigaction sigpipe_action; | 1617 | struct sigaction sigpipe_action; |
| @@ -1765,12 +1763,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1765 | int xforkin = forkin; | 1763 | int xforkin = forkin; |
| 1766 | int xforkout = forkout; | 1764 | int xforkout = forkout; |
| 1767 | 1765 | ||
| 1768 | #if 0 /* This was probably a mistake--it duplicates code later on, | ||
| 1769 | but fails to handle all the cases. */ | ||
| 1770 | /* Make sure SIGCHLD is not blocked in the child. */ | ||
| 1771 | sigsetmask (SIGEMPTYMASK); | ||
| 1772 | #endif | ||
| 1773 | |||
| 1774 | /* Make the pty be the controlling terminal of the process. */ | 1766 | /* Make the pty be the controlling terminal of the process. */ |
| 1775 | #ifdef HAVE_PTYS | 1767 | #ifdef HAVE_PTYS |
| 1776 | /* First, disconnect its current controlling terminal. */ | 1768 | /* First, disconnect its current controlling terminal. */ |
| @@ -5434,7 +5426,10 @@ static Lisp_Object process_sent_to; | |||
| 5434 | static _Noreturn void | 5426 | static _Noreturn void |
| 5435 | handle_pipe_signal (int sig) | 5427 | handle_pipe_signal (int sig) |
| 5436 | { | 5428 | { |
| 5437 | sigunblock (sigmask (SIGPIPE)); | 5429 | sigset_t unblocked; |
| 5430 | sigemptyset (&unblocked); | ||
| 5431 | sigaddset (&unblocked, SIGPIPE); | ||
| 5432 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 5438 | _longjmp (send_process_frame, 1); | 5433 | _longjmp (send_process_frame, 1); |
| 5439 | } | 5434 | } |
| 5440 | 5435 | ||
| @@ -5534,7 +5529,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5534 | struct Lisp_Process *p = XPROCESS (proc); | 5529 | struct Lisp_Process *p = XPROCESS (proc); |
| 5535 | ssize_t rv; | 5530 | ssize_t rv; |
| 5536 | struct coding_system *coding; | 5531 | struct coding_system *coding; |
| 5537 | void (*volatile old_sigpipe) (int); | 5532 | struct sigaction old_sigpipe_action; |
| 5538 | 5533 | ||
| 5539 | if (p->raw_status_new) | 5534 | if (p->raw_status_new) |
| 5540 | update_status (p); | 5535 | update_status (p); |
| @@ -5673,7 +5668,9 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5673 | /* Send this batch, using one or more write calls. */ | 5668 | /* Send this batch, using one or more write calls. */ |
| 5674 | ptrdiff_t written = 0; | 5669 | ptrdiff_t written = 0; |
| 5675 | int outfd = p->outfd; | 5670 | int outfd = p->outfd; |
| 5676 | old_sigpipe = signal (SIGPIPE, deliver_pipe_signal); | 5671 | struct sigaction action; |
| 5672 | emacs_sigaction_init (&action, deliver_pipe_signal); | ||
| 5673 | sigaction (SIGPIPE, &action, &old_sigpipe_action); | ||
| 5677 | #ifdef DATAGRAM_SOCKETS | 5674 | #ifdef DATAGRAM_SOCKETS |
| 5678 | if (DATAGRAM_CHAN_P (outfd)) | 5675 | if (DATAGRAM_CHAN_P (outfd)) |
| 5679 | { | 5676 | { |
| @@ -5684,7 +5681,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5684 | written = rv; | 5681 | written = rv; |
| 5685 | else if (errno == EMSGSIZE) | 5682 | else if (errno == EMSGSIZE) |
| 5686 | { | 5683 | { |
| 5687 | signal (SIGPIPE, old_sigpipe); | 5684 | sigaction (SIGPIPE, &old_sigpipe_action, 0); |
| 5688 | report_file_error ("sending datagram", | 5685 | report_file_error ("sending datagram", |
| 5689 | Fcons (proc, Qnil)); | 5686 | Fcons (proc, Qnil)); |
| 5690 | } | 5687 | } |
| @@ -5709,7 +5706,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5709 | } | 5706 | } |
| 5710 | #endif | 5707 | #endif |
| 5711 | } | 5708 | } |
| 5712 | signal (SIGPIPE, old_sigpipe); | 5709 | sigaction (SIGPIPE, &old_sigpipe_action, 0); |
| 5713 | 5710 | ||
| 5714 | if (rv < 0) | 5711 | if (rv < 0) |
| 5715 | { | 5712 | { |
| @@ -5769,7 +5766,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf, | |||
| 5769 | } | 5766 | } |
| 5770 | else | 5767 | else |
| 5771 | { | 5768 | { |
| 5772 | signal (SIGPIPE, old_sigpipe); | 5769 | sigaction (SIGPIPE, &old_sigpipe_action, 0); |
| 5773 | proc = process_sent_to; | 5770 | proc = process_sent_to; |
| 5774 | p = XPROCESS (proc); | 5771 | p = XPROCESS (proc); |
| 5775 | p->raw_status_new = 0; | 5772 | p->raw_status_new = 0; |
| @@ -7389,7 +7386,11 @@ init_process_emacs (void) | |||
| 7389 | #ifndef CANNOT_DUMP | 7386 | #ifndef CANNOT_DUMP |
| 7390 | if (! noninteractive || initialized) | 7387 | if (! noninteractive || initialized) |
| 7391 | #endif | 7388 | #endif |
| 7392 | signal (SIGCHLD, deliver_child_signal); | 7389 | { |
| 7390 | struct sigaction action; | ||
| 7391 | emacs_sigaction_init (&action, deliver_child_signal); | ||
| 7392 | sigaction (SIGCHLD, &action, 0); | ||
| 7393 | } | ||
| 7393 | #endif | 7394 | #endif |
| 7394 | 7395 | ||
| 7395 | FD_ZERO (&input_wait_mask); | 7396 | FD_ZERO (&input_wait_mask); |