1 /* signals.c -- signal handling support for readline. */
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
22 #define READLINE_LIBRARY
24 #if defined (HAVE_CONFIG_H)
28 #include <stdio.h> /* Just for NULL. Yuck. */
29 #include <sys/types.h>
32 #if defined (HAVE_UNISTD_H)
34 #endif /* HAVE_UNISTD_H */
36 /* System-specific feature definitions and include files. */
39 #if defined (GWINSZ_IN_SYS_IOCTL)
40 # include <sys/ioctl.h>
41 #endif /* GWINSZ_IN_SYS_IOCTL */
43 /* Some standard library routines. */
47 #include "rlprivate.h"
49 #if defined (HANDLE_SIGNALS)
51 #if !defined (RETSIGTYPE)
52 # if defined (VOID_SIGHANDLER)
53 # define RETSIGTYPE void
55 # define RETSIGTYPE int
56 # endif /* !VOID_SIGHANDLER */
57 #endif /* !RETSIGTYPE */
59 #if defined (VOID_SIGHANDLER)
60 # define SIGHANDLER_RETURN return
62 # define SIGHANDLER_RETURN return (0)
65 /* This typedef is equivalent to the one for Function; it allows us
66 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
67 typedef RETSIGTYPE SigHandler ();
69 #if defined (HAVE_POSIX_SIGNALS)
70 typedef struct sigaction sighandler_cxt;
71 # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
73 typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
74 # define sigemptyset(m)
75 #endif /* !HAVE_POSIX_SIGNALS */
81 static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
82 static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
84 static RETSIGTYPE rl_signal_handler PARAMS((int));
85 static RETSIGTYPE _rl_handle_signal PARAMS((int));
87 /* Exported variables for use by applications. */
89 /* If non-zero, readline will install its own signal handlers for
90 SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
91 int rl_catch_signals = 1;
93 /* If non-zero, readline will install a signal handler for SIGWINCH. */
95 int rl_catch_sigwinch = 1;
97 int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
100 /* Private variables. */
101 int _rl_interrupt_immediately = 0;
102 int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
104 /* If non-zero, print characters corresponding to received signals. */
107 int _rl_intr_char = 0;
108 int _rl_quit_char = 0;
109 int _rl_susp_char = 0;
111 static int signals_set_flag;
112 static int sigwinch_set_flag;
114 /* **************************************************************** */
116 /* Signal Handling */
118 /* **************************************************************** */
120 static sighandler_cxt old_int, old_term, old_alrm, old_quit;
121 #if defined (SIGTSTP)
122 static sighandler_cxt old_tstp, old_ttou, old_ttin;
124 #if defined (SIGWINCH)
125 static sighandler_cxt old_winch;
128 /* Readline signal handler functions. */
130 /* Called from RL_CHECK_SIGNALS() macro */
132 _rl_signal_handler (sig)
134 _rl_caught_signal = 0; /* XXX */
136 _rl_handle_signal (sig);
141 rl_signal_handler (sig)
144 if (_rl_interrupt_immediately)
146 _rl_interrupt_immediately = 0;
147 _rl_handle_signal (sig);
150 _rl_caught_signal = sig;
155 _rl_handle_signal (sig)
158 #if defined (HAVE_POSIX_SIGNALS)
160 #else /* !HAVE_POSIX_SIGNALS */
161 # if defined (HAVE_BSD_SIGNALS)
163 # else /* !HAVE_BSD_SIGNALS */
164 sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
165 # endif /* !HAVE_BSD_SIGNALS */
166 #endif /* !HAVE_POSIX_SIGNALS */
168 RL_SETSTATE(RL_STATE_SIGHANDLER);
170 #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
171 /* Since the signal will not be blocked while we are in the signal
172 handler, ignore it until rl_clear_signals resets the catcher. */
173 # if defined (SIGALRM)
174 if (sig == SIGINT || sig == SIGALRM)
178 rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
179 #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
184 _rl_reset_completion_state ();
185 rl_free_line_state ();
189 #if defined (SIGTSTP)
194 #if defined (SIGALRM)
197 #if defined (SIGQUIT)
200 rl_echo_signal_char (sig);
201 rl_cleanup_after_signal ();
203 #if defined (HAVE_POSIX_SIGNALS)
205 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
206 sigdelset (&set, sig);
207 #else /* !HAVE_POSIX_SIGNALS */
208 # if defined (HAVE_BSD_SIGNALS)
209 omask = sigblock (0);
210 # endif /* HAVE_BSD_SIGNALS */
211 #endif /* !HAVE_POSIX_SIGNALS */
213 #if defined (__EMX__)
214 signal (sig, SIG_ACK);
217 #if defined (HAVE_KILL)
218 kill (getpid (), sig);
220 raise (sig); /* assume we have raise */
223 /* Let the signal that we just sent through. */
224 #if defined (HAVE_POSIX_SIGNALS)
225 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
226 #else /* !HAVE_POSIX_SIGNALS */
227 # if defined (HAVE_BSD_SIGNALS)
228 sigsetmask (omask & ~(sigmask (sig)));
229 # endif /* HAVE_BSD_SIGNALS */
230 #endif /* !HAVE_POSIX_SIGNALS */
232 rl_reset_after_signal ();
235 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
239 #if defined (SIGWINCH)
241 rl_sigwinch_handler (sig)
246 #if defined (MUST_REINSTALL_SIGHANDLERS)
247 sighandler_cxt dummy_winch;
249 /* We don't want to change old_winch -- it holds the state of SIGWINCH
250 disposition set by the calling application. We need this state
251 because we call the application's SIGWINCH handler after updating
252 our own idea of the screen size. */
253 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
256 RL_SETSTATE(RL_STATE_SIGHANDLER);
257 rl_resize_terminal ();
259 /* If another sigwinch handler has been installed, call it. */
260 oh = (SigHandler *)old_winch.sa_handler;
261 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
264 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
267 #endif /* SIGWINCH */
269 /* Functions to manage signal handling. */
271 #if !defined (HAVE_POSIX_SIGNALS)
273 rl_sigaction (sig, nh, oh)
275 sighandler_cxt *nh, *oh;
277 oh->sa_handler = signal (sig, nh->sa_handler);
280 #endif /* !HAVE_POSIX_SIGNALS */
282 /* Set up a readline-specific signal handler, saving the old signal
283 information in OHANDLER. Return the old signal handler, like
286 rl_set_sighandler (sig, handler, ohandler)
289 sighandler_cxt *ohandler;
291 sighandler_cxt old_handler;
292 #if defined (HAVE_POSIX_SIGNALS)
293 struct sigaction act;
295 act.sa_handler = handler;
296 # if defined (SIGWINCH)
297 act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
300 # endif /* SIGWINCH */
301 sigemptyset (&act.sa_mask);
302 sigemptyset (&ohandler->sa_mask);
303 sigaction (sig, &act, &old_handler);
305 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
306 #endif /* !HAVE_POSIX_SIGNALS */
308 /* XXX -- assume we have memcpy */
309 /* If rl_set_signals is called twice in a row, don't set the old handler to
310 rl_signal_handler, because that would cause infinite recursion. */
311 if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
312 memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
314 return (ohandler->sa_handler);
318 rl_maybe_set_sighandler (sig, handler, ohandler)
321 sighandler_cxt *ohandler;
323 sighandler_cxt dummy;
326 sigemptyset (&dummy.sa_mask);
327 oh = rl_set_sighandler (sig, handler, ohandler);
328 if (oh == (SigHandler *)SIG_IGN)
329 rl_sigaction (sig, ohandler, &dummy);
335 sighandler_cxt dummy;
337 #if defined (HAVE_POSIX_SIGNALS)
338 static int sigmask_set = 0;
339 static sigset_t bset, oset;
342 #if defined (HAVE_POSIX_SIGNALS)
343 if (rl_catch_signals && sigmask_set == 0)
347 sigaddset (&bset, SIGINT);
348 sigaddset (&bset, SIGTERM);
349 #if defined (SIGQUIT)
350 sigaddset (&bset, SIGQUIT);
352 #if defined (SIGALRM)
353 sigaddset (&bset, SIGALRM);
355 #if defined (SIGTSTP)
356 sigaddset (&bset, SIGTSTP);
358 #if defined (SIGTTIN)
359 sigaddset (&bset, SIGTTIN);
361 #if defined (SIGTTOU)
362 sigaddset (&bset, SIGTTOU);
366 #endif /* HAVE_POSIX_SIGNALS */
368 if (rl_catch_signals && signals_set_flag == 0)
370 #if defined (HAVE_POSIX_SIGNALS)
372 sigprocmask (SIG_BLOCK, &bset, &oset);
375 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
376 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
377 #if defined (SIGQUIT)
378 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
381 #if defined (SIGALRM)
382 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
383 if (oh == (SigHandler *)SIG_IGN)
384 rl_sigaction (SIGALRM, &old_alrm, &dummy);
385 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
386 /* If the application using readline has already installed a signal
387 handler with SA_RESTART, SIGALRM will cause reads to be restarted
388 automatically, so readline should just get out of the way. Since
389 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
390 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
391 rl_sigaction (SIGALRM, &old_alrm, &dummy);
392 #endif /* HAVE_POSIX_SIGNALS */
395 #if defined (SIGTSTP)
396 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
399 #if defined (SIGTTOU)
400 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
403 #if defined (SIGTTIN)
404 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
407 signals_set_flag = 1;
409 #if defined (HAVE_POSIX_SIGNALS)
410 sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
414 #if defined (SIGWINCH)
415 if (rl_catch_sigwinch && sigwinch_set_flag == 0)
417 rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
418 sigwinch_set_flag = 1;
420 #endif /* SIGWINCH */
428 sighandler_cxt dummy;
430 if (rl_catch_signals && signals_set_flag == 1)
432 sigemptyset (&dummy.sa_mask);
434 rl_sigaction (SIGINT, &old_int, &dummy);
435 rl_sigaction (SIGTERM, &old_term, &dummy);
436 #if defined (SIGQUIT)
437 rl_sigaction (SIGQUIT, &old_quit, &dummy);
439 #if defined (SIGALRM)
440 rl_sigaction (SIGALRM, &old_alrm, &dummy);
443 #if defined (SIGTSTP)
444 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
447 #if defined (SIGTTOU)
448 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
451 #if defined (SIGTTIN)
452 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
455 signals_set_flag = 0;
458 #if defined (SIGWINCH)
459 if (rl_catch_sigwinch && sigwinch_set_flag == 1)
461 sigemptyset (&dummy.sa_mask);
462 rl_sigaction (SIGWINCH, &old_winch, &dummy);
463 sigwinch_set_flag = 0;
470 /* Clean up the terminal and readline state after catching a signal, before
471 resending it to the calling application. */
473 rl_cleanup_after_signal ()
475 _rl_clean_up_for_exit ();
476 if (rl_deprep_term_function)
477 (*rl_deprep_term_function) ();
478 rl_clear_pending_input ();
482 /* Reset the terminal and readline state after a signal handler returns. */
484 rl_reset_after_signal ()
486 if (rl_prep_term_function)
487 (*rl_prep_term_function) (_rl_meta_flag);
491 /* Free up the readline variable line state for the current line (undo list,
492 any partial history entry, any keyboard macros in progress, and any
493 numeric arguments in process) after catching a signal, before calling
494 rl_cleanup_after_signal(). */
496 rl_free_line_state ()
498 register HIST_ENTRY *entry;
500 rl_free_undo_list ();
502 entry = current_history ();
504 entry->data = (char *)NULL;
506 _rl_kill_kbd_macro ();
508 _rl_reset_argument ();
511 #endif /* HANDLE_SIGNALS */
513 /* **************************************************************** */
515 /* SIGINT Management */
517 /* **************************************************************** */
519 #if defined (HAVE_POSIX_SIGNALS)
520 static sigset_t sigint_set, sigint_oset;
521 #else /* !HAVE_POSIX_SIGNALS */
522 # if defined (HAVE_BSD_SIGNALS)
523 static int sigint_oldmask;
524 # endif /* HAVE_BSD_SIGNALS */
525 #endif /* !HAVE_POSIX_SIGNALS */
527 static int sigint_blocked;
529 /* Cause SIGINT to not be delivered until the corresponding call to
537 #if defined (HAVE_POSIX_SIGNALS)
538 sigemptyset (&sigint_set);
539 sigemptyset (&sigint_oset);
540 sigaddset (&sigint_set, SIGINT);
541 sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
542 #else /* !HAVE_POSIX_SIGNALS */
543 # if defined (HAVE_BSD_SIGNALS)
544 sigint_oldmask = sigblock (sigmask (SIGINT));
545 # else /* !HAVE_BSD_SIGNALS */
546 # if defined (HAVE_USG_SIGHOLD)
548 # endif /* HAVE_USG_SIGHOLD */
549 # endif /* !HAVE_BSD_SIGNALS */
550 #endif /* !HAVE_POSIX_SIGNALS */
555 /* Allow SIGINT to be delivered. */
557 _rl_release_sigint ()
559 if (sigint_blocked == 0)
562 #if defined (HAVE_POSIX_SIGNALS)
563 sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
565 # if defined (HAVE_BSD_SIGNALS)
566 sigsetmask (sigint_oldmask);
567 # else /* !HAVE_BSD_SIGNALS */
568 # if defined (HAVE_USG_SIGHOLD)
570 # endif /* HAVE_USG_SIGHOLD */
571 # endif /* !HAVE_BSD_SIGNALS */
572 #endif /* !HAVE_POSIX_SIGNALS */
577 /* **************************************************************** */
579 /* Echoing special control characters */
581 /* **************************************************************** */
583 rl_echo_signal_char (sig)
589 if (_rl_echoctl == 0)
594 case SIGINT: c = _rl_intr_char; break;
595 case SIGQUIT: c = _rl_quit_char; break;
596 case SIGTSTP: c = _rl_susp_char; break;
600 if (CTRL_CHAR (c) || c == RUBOUT)
603 cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
604 cstr[cslen = 2] = '\0';
609 cstr[cslen = 1] = '\0';
612 _rl_output_some_chars (cstr, cslen);