aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorPaul Eggert2012-09-06 18:27:44 -0700
committerPaul Eggert2012-09-06 18:27:44 -0700
commit2fe282993cf9c84f5be424dc93d03f9705a7edd8 (patch)
tree229edb6fe29e66984b2992f3f9fa081cd7fe8920 /src/keyboard.c
parent845ce106c0ab157e25416964330875ad6c24b699 (diff)
downloademacs-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/keyboard.c')
-rw-r--r--src/keyboard.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 128f9280911..d26cf35e108 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#define KEYBOARD_INLINE EXTERN_INLINE 22#define KEYBOARD_INLINE EXTERN_INLINE
23 23
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27#include "lisp.h" 26#include "lisp.h"
@@ -3680,7 +3679,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
3680 if (immediate_quit && NILP (Vinhibit_quit)) 3679 if (immediate_quit && NILP (Vinhibit_quit))
3681 { 3680 {
3682 immediate_quit = 0; 3681 immediate_quit = 0;
3683 sigfree (); 3682 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
3684 QUIT; 3683 QUIT;
3685 } 3684 }
3686 } 3685 }
@@ -3832,7 +3831,11 @@ kbd_buffer_get_event (KBOARD **kbp,
3832 unhold_keyboard_input (); 3831 unhold_keyboard_input ();
3833#ifdef SIGIO 3832#ifdef SIGIO
3834 if (!noninteractive) 3833 if (!noninteractive)
3835 signal (SIGIO, deliver_input_available_signal); 3834 {
3835 struct sigaction action;
3836 emacs_sigaction_init (&action, deliver_input_available_signal);
3837 sigaction (SIGIO, &action, 0);
3838 }
3836#endif /* SIGIO */ 3839#endif /* SIGIO */
3837 start_polling (); 3840 start_polling ();
3838 } 3841 }
@@ -6780,10 +6783,12 @@ gobble_input (int expected)
6780#ifdef SIGIO 6783#ifdef SIGIO
6781 if (interrupt_input) 6784 if (interrupt_input)
6782 { 6785 {
6783 SIGMASKTYPE mask; 6786 sigset_t blocked, procmask;
6784 mask = sigblock (sigmask (SIGIO)); 6787 sigemptyset (&blocked);
6788 sigaddset (&blocked, SIGIO);
6789 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6785 read_avail_input (expected); 6790 read_avail_input (expected);
6786 sigsetmask (mask); 6791 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6787 } 6792 }
6788 else 6793 else
6789#ifdef POLL_FOR_INPUT 6794#ifdef POLL_FOR_INPUT
@@ -6792,10 +6797,12 @@ gobble_input (int expected)
6792 it's always set. */ 6797 it's always set. */
6793 if (!interrupt_input && poll_suppress_count == 0) 6798 if (!interrupt_input && poll_suppress_count == 0)
6794 { 6799 {
6795 SIGMASKTYPE mask; 6800 sigset_t blocked, procmask;
6796 mask = sigblock (sigmask (SIGALRM)); 6801 sigemptyset (&blocked);
6802 sigaddset (&blocked, SIGALRM);
6803 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6797 read_avail_input (expected); 6804 read_avail_input (expected);
6798 sigsetmask (mask); 6805 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6799 } 6806 }
6800 else 6807 else
6801#endif 6808#endif
@@ -6831,10 +6838,12 @@ record_asynch_buffer_change (void)
6831#ifdef SIGIO 6838#ifdef SIGIO
6832 if (interrupt_input) 6839 if (interrupt_input)
6833 { 6840 {
6834 SIGMASKTYPE mask; 6841 sigset_t blocked, procmask;
6835 mask = sigblock (sigmask (SIGIO)); 6842 sigemptyset (&blocked);
6843 sigaddset (&blocked, SIGIO);
6844 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6836 kbd_buffer_store_event (&event); 6845 kbd_buffer_store_event (&event);
6837 sigsetmask (mask); 6846 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6838 } 6847 }
6839 else 6848 else
6840#endif 6849#endif
@@ -7295,6 +7304,7 @@ static struct user_signal_info *user_signals = NULL;
7295void 7304void
7296add_user_signal (int sig, const char *name) 7305add_user_signal (int sig, const char *name)
7297{ 7306{
7307 struct sigaction action;
7298 struct user_signal_info *p; 7308 struct user_signal_info *p;
7299 7309
7300 for (p = user_signals; p; p = p->next) 7310 for (p = user_signals; p; p = p->next)
@@ -7309,7 +7319,8 @@ add_user_signal (int sig, const char *name)
7309 p->next = user_signals; 7319 p->next = user_signals;
7310 user_signals = p; 7320 user_signals = p;
7311 7321
7312 signal (sig, deliver_user_signal); 7322 emacs_sigaction_init (&action, deliver_user_signal);
7323 sigaction (sig, &action, 0);
7313} 7324}
7314 7325
7315static void 7326static void
@@ -7381,7 +7392,7 @@ store_user_signal_events (void)
7381 for (p = user_signals; p; p = p->next) 7392 for (p = user_signals; p; p = p->next)
7382 if (p->npending > 0) 7393 if (p->npending > 0)
7383 { 7394 {
7384 SIGMASKTYPE mask; 7395 sigset_t blocked, procmask;
7385 7396
7386 if (nstored == 0) 7397 if (nstored == 0)
7387 { 7398 {
@@ -7391,7 +7402,10 @@ store_user_signal_events (void)
7391 } 7402 }
7392 nstored += p->npending; 7403 nstored += p->npending;
7393 7404
7394 mask = sigblock (sigmask (p->sig)); 7405 sigemptyset (&blocked);
7406 sigaddset (&blocked, p->sig);
7407 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
7408
7395 do 7409 do
7396 { 7410 {
7397 buf.code = p->sig; 7411 buf.code = p->sig;
@@ -7399,7 +7413,8 @@ store_user_signal_events (void)
7399 p->npending--; 7413 p->npending--;
7400 } 7414 }
7401 while (p->npending > 0); 7415 while (p->npending > 0);
7402 sigsetmask (mask); 7416
7417 pthread_sigmask (SIG_SETMASK, &procmask, 0);
7403 } 7418 }
7404 7419
7405 return nstored; 7420 return nstored;
@@ -10838,7 +10853,10 @@ handle_interrupt (void)
10838 /* If SIGINT isn't blocked, don't let us be interrupted by 10853 /* If SIGINT isn't blocked, don't let us be interrupted by
10839 another SIGINT, it might be harmful due to non-reentrancy 10854 another SIGINT, it might be harmful due to non-reentrancy
10840 in I/O functions. */ 10855 in I/O functions. */
10841 sigblock (sigmask (SIGINT)); 10856 sigset_t blocked;
10857 sigemptyset (&blocked);
10858 sigaddset (&blocked, SIGINT);
10859 pthread_sigmask (SIG_BLOCK, &blocked, 0);
10842 10860
10843 fflush (stdout); 10861 fflush (stdout);
10844 reset_all_sys_modes (); 10862 reset_all_sys_modes ();
@@ -10909,7 +10927,7 @@ handle_interrupt (void)
10909#endif /* not MSDOS */ 10927#endif /* not MSDOS */
10910 fflush (stdout); 10928 fflush (stdout);
10911 init_all_sys_modes (); 10929 init_all_sys_modes ();
10912 sigfree (); 10930 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10913 } 10931 }
10914 else 10932 else
10915 { 10933 {
@@ -10922,7 +10940,7 @@ handle_interrupt (void)
10922 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 10940 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
10923 10941
10924 immediate_quit = 0; 10942 immediate_quit = 0;
10925 sigfree (); 10943 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10926 saved = gl_state; 10944 saved = gl_state;
10927 GCPRO4 (saved.object, saved.global_code, 10945 GCPRO4 (saved.object, saved.global_code,
10928 saved.current_syntax_table, saved.old_prop); 10946 saved.current_syntax_table, saved.old_prop);
@@ -10967,7 +10985,7 @@ quit_throw_to_read_char (int from_signal)
10967 if (!from_signal && EQ (Vquit_flag, Qkill_emacs)) 10985 if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
10968 Fkill_emacs (Qnil); 10986 Fkill_emacs (Qnil);
10969 10987
10970 sigfree (); 10988 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10971 /* Prevent another signal from doing this before we finish. */ 10989 /* Prevent another signal from doing this before we finish. */
10972 clear_waiting_for_input (); 10990 clear_waiting_for_input ();
10973 input_pending = 0; 10991 input_pending = 0;
@@ -11402,17 +11420,23 @@ init_keyboard (void)
11402 SIGINT. There is special code in interrupt_signal to exit 11420 SIGINT. There is special code in interrupt_signal to exit
11403 Emacs on SIGINT when there are no termcap frames on the 11421 Emacs on SIGINT when there are no termcap frames on the
11404 controlling terminal. */ 11422 controlling terminal. */
11405 signal (SIGINT, deliver_interrupt_signal); 11423 struct sigaction action;
11424 emacs_sigaction_init (&action, deliver_interrupt_signal);
11425 sigaction (SIGINT, &action, 0);
11406#ifndef DOS_NT 11426#ifndef DOS_NT
11407 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and 11427 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
11408 SIGQUIT and we can't tell which one it will give us. */ 11428 SIGQUIT and we can't tell which one it will give us. */
11409 signal (SIGQUIT, deliver_interrupt_signal); 11429 sigaction (SIGQUIT, &action, 0);
11410#endif /* not DOS_NT */ 11430#endif /* not DOS_NT */
11411 } 11431 }
11412/* Note SIGIO has been undef'd if FIONREAD is missing. */ 11432/* Note SIGIO has been undef'd if FIONREAD is missing. */
11413#ifdef SIGIO 11433#ifdef SIGIO
11414 if (!noninteractive) 11434 if (!noninteractive)
11415 signal (SIGIO, deliver_input_available_signal); 11435 {
11436 struct sigaction action;
11437 emacs_sigaction_init (&action, deliver_input_available_signal);
11438 sigaction (SIGIO, &action, 0);
11439 }
11416#endif /* SIGIO */ 11440#endif /* SIGIO */
11417 11441
11418/* Use interrupt input by default, if it works and noninterrupt input 11442/* Use interrupt input by default, if it works and noninterrupt input
@@ -11424,7 +11448,7 @@ init_keyboard (void)
11424 interrupt_input = 0; 11448 interrupt_input = 0;
11425#endif 11449#endif
11426 11450
11427 sigfree (); 11451 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
11428 dribble = 0; 11452 dribble = 0;
11429 11453
11430 if (keyboard_init_hook) 11454 if (keyboard_init_hook)