blob: 61f02f9f77603f5b01694b844087664f6f7f1d5f [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* signals.c -- signal handling support for readline. */
2
Chet Rameyac50fba2014-02-26 09:36:43 -05003/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
Jari Aalto31859422009-01-12 13:36:28 +00005 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
Jari Aalto726f6381996-08-26 18:22:31 +00007
Jari Aalto31859422009-01-12 13:36:28 +00008 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
Jari Aalto726f6381996-08-26 18:22:31 +000011 (at your option) any later version.
12
Jari Aalto31859422009-01-12 13:36:28 +000013 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
Jari Aalto726f6381996-08-26 18:22:31 +000016 GNU General Public License for more details.
17
Jari Aalto31859422009-01-12 13:36:28 +000018 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20*/
21
Jari Aalto726f6381996-08-26 18:22:31 +000022#define READLINE_LIBRARY
23
Jari Aaltoccc6cda1996-12-23 17:02:34 +000024#if defined (HAVE_CONFIG_H)
25# include <config.h>
26#endif
27
28#include <stdio.h> /* Just for NULL. Yuck. */
Jari Aalto726f6381996-08-26 18:22:31 +000029#include <sys/types.h>
Jari Aalto726f6381996-08-26 18:22:31 +000030#include <signal.h>
31
32#if defined (HAVE_UNISTD_H)
33# include <unistd.h>
34#endif /* HAVE_UNISTD_H */
35
Jari Aalto726f6381996-08-26 18:22:31 +000036/* System-specific feature definitions and include files. */
37#include "rldefs.h"
38
39#if defined (GWINSZ_IN_SYS_IOCTL)
40# include <sys/ioctl.h>
41#endif /* GWINSZ_IN_SYS_IOCTL */
42
43/* Some standard library routines. */
44#include "readline.h"
45#include "history.h"
46
Jari Aaltobb706242000-03-17 21:46:59 +000047#include "rlprivate.h"
48
Jari Aalto31859422009-01-12 13:36:28 +000049#if defined (HANDLE_SIGNALS)
50
Jari Aaltoccc6cda1996-12-23 17:02:34 +000051#if !defined (RETSIGTYPE)
52# if defined (VOID_SIGHANDLER)
53# define RETSIGTYPE void
54# else
55# define RETSIGTYPE int
56# endif /* !VOID_SIGHANDLER */
57#endif /* !RETSIGTYPE */
Jari Aalto726f6381996-08-26 18:22:31 +000058
59#if defined (VOID_SIGHANDLER)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000060# define SIGHANDLER_RETURN return
Jari Aalto726f6381996-08-26 18:22:31 +000061#else
Jari Aaltoccc6cda1996-12-23 17:02:34 +000062# define SIGHANDLER_RETURN return (0)
63#endif
Jari Aalto726f6381996-08-26 18:22:31 +000064
Jari Aalto28ef6c32001-04-06 19:14:31 +000065/* This typedef is equivalent to the one for Function; it allows us
Jari Aalto726f6381996-08-26 18:22:31 +000066 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000067typedef RETSIGTYPE SigHandler ();
Jari Aalto726f6381996-08-26 18:22:31 +000068
Jari Aaltobb706242000-03-17 21:46:59 +000069#if defined (HAVE_POSIX_SIGNALS)
70typedef struct sigaction sighandler_cxt;
71# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
72#else
73typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
74# define sigemptyset(m)
75#endif /* !HAVE_POSIX_SIGNALS */
Jari Aaltob72432f1999-02-19 17:11:39 +000076
Jari Aaltob80f6442004-07-27 13:29:18 +000077#ifndef SA_RESTART
78# define SA_RESTART 0
79#endif
80
Jari Aaltof73dda02001-11-13 17:56:06 +000081static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
Jari Aalto7117c2d2002-07-17 14:10:11 +000082static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
Chet Rameyac50fba2014-02-26 09:36:43 -050083static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *));
Jari Aalto726f6381996-08-26 18:22:31 +000084
Jari Aalto17345e52009-02-19 22:21:29 +000085static RETSIGTYPE rl_signal_handler PARAMS((int));
86static RETSIGTYPE _rl_handle_signal PARAMS((int));
87
Jari Aaltob72432f1999-02-19 17:11:39 +000088/* Exported variables for use by applications. */
89
90/* If non-zero, readline will install its own signal handlers for
Chet Rameyac50fba2014-02-26 09:36:43 -050091 SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
Jari Aaltob72432f1999-02-19 17:11:39 +000092int rl_catch_signals = 1;
93
94/* If non-zero, readline will install a signal handler for SIGWINCH. */
95#ifdef SIGWINCH
96int rl_catch_sigwinch = 1;
Jari Aaltob80f6442004-07-27 13:29:18 +000097#else
98int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
Jari Aaltob72432f1999-02-19 17:11:39 +000099#endif
100
Jari Aalto31859422009-01-12 13:36:28 +0000101/* Private variables. */
Jari Aalto17345e52009-02-19 22:21:29 +0000102int _rl_interrupt_immediately = 0;
103int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
104
Chet Ramey00018032011-11-21 20:51:19 -0500105/* If non-zero, print characters corresponding to received signals as long as
106 the user has indicated his desire to do so (_rl_echo_control_chars). */
Jari Aalto31859422009-01-12 13:36:28 +0000107int _rl_echoctl = 0;
108
109int _rl_intr_char = 0;
110int _rl_quit_char = 0;
111int _rl_susp_char = 0;
112
Jari Aaltob72432f1999-02-19 17:11:39 +0000113static int signals_set_flag;
114static int sigwinch_set_flag;
115
Jari Aalto726f6381996-08-26 18:22:31 +0000116/* **************************************************************** */
117/* */
118/* Signal Handling */
119/* */
120/* **************************************************************** */
121
Chet Rameyac50fba2014-02-26 09:36:43 -0500122static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit;
Jari Aaltob72432f1999-02-19 17:11:39 +0000123#if defined (SIGTSTP)
Jari Aaltod166f041997-06-05 14:59:13 +0000124static sighandler_cxt old_tstp, old_ttou, old_ttin;
Jari Aaltod166f041997-06-05 14:59:13 +0000125#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000126#if defined (SIGWINCH)
127static sighandler_cxt old_winch;
128#endif
129
Chet Rameyac50fba2014-02-26 09:36:43 -0500130_rl_sigcleanup_func_t *_rl_sigcleanup;
131void *_rl_sigcleanarg;
132
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000133/* Readline signal handler functions. */
134
Jari Aalto17345e52009-02-19 22:21:29 +0000135/* Called from RL_CHECK_SIGNALS() macro */
136RETSIGTYPE
137_rl_signal_handler (sig)
Chet Ramey495aee42011-11-22 19:11:26 -0500138 int sig;
Jari Aalto17345e52009-02-19 22:21:29 +0000139{
140 _rl_caught_signal = 0; /* XXX */
141
Chet Rameyac50fba2014-02-26 09:36:43 -0500142#if defined (SIGWINCH)
143 if (sig == SIGWINCH)
144 {
145 rl_resize_terminal ();
146 /* XXX - experimental for now */
147 /* Call a signal hook because though we called the original signal handler
148 in rl_sigwinch_handler below, we will not resend the signal to
149 ourselves. */
150 if (rl_signal_event_hook)
151 (*rl_signal_event_hook) ();
152 }
153 else
154#endif
155 _rl_handle_signal (sig);
156
Jari Aalto17345e52009-02-19 22:21:29 +0000157 SIGHANDLER_RETURN;
158}
159
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000160static RETSIGTYPE
Jari Aalto726f6381996-08-26 18:22:31 +0000161rl_signal_handler (sig)
162 int sig;
163{
Chet Rameyac50fba2014-02-26 09:36:43 -0500164 if (_rl_interrupt_immediately)
Jari Aalto17345e52009-02-19 22:21:29 +0000165 {
166 _rl_interrupt_immediately = 0;
167 _rl_handle_signal (sig);
168 }
Chet Ramey00018032011-11-21 20:51:19 -0500169 else
170 _rl_caught_signal = sig;
Jari Aalto17345e52009-02-19 22:21:29 +0000171
Jari Aalto17345e52009-02-19 22:21:29 +0000172 SIGHANDLER_RETURN;
173}
174
175static RETSIGTYPE
176_rl_handle_signal (sig)
177 int sig;
178{
Jari Aalto726f6381996-08-26 18:22:31 +0000179#if defined (HAVE_POSIX_SIGNALS)
180 sigset_t set;
181#else /* !HAVE_POSIX_SIGNALS */
182# if defined (HAVE_BSD_SIGNALS)
183 long omask;
Jari Aaltod166f041997-06-05 14:59:13 +0000184# else /* !HAVE_BSD_SIGNALS */
185 sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
186# endif /* !HAVE_BSD_SIGNALS */
Jari Aalto726f6381996-08-26 18:22:31 +0000187#endif /* !HAVE_POSIX_SIGNALS */
188
Jari Aalto28ef6c32001-04-06 19:14:31 +0000189 RL_SETSTATE(RL_STATE_SIGHANDLER);
190
Jari Aalto726f6381996-08-26 18:22:31 +0000191#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
192 /* Since the signal will not be blocked while we are in the signal
193 handler, ignore it until rl_clear_signals resets the catcher. */
Jari Aalto95732b42005-12-07 14:08:12 +0000194# if defined (SIGALRM)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000195 if (sig == SIGINT || sig == SIGALRM)
Jari Aalto95732b42005-12-07 14:08:12 +0000196# else
197 if (sig == SIGINT)
198# endif
Jari Aaltod166f041997-06-05 14:59:13 +0000199 rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000200#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
Jari Aalto726f6381996-08-26 18:22:31 +0000201
Chet Rameyac50fba2014-02-26 09:36:43 -0500202 /* If there's a sig cleanup function registered, call it and `deregister'
203 the cleanup function to avoid multiple calls */
204 if (_rl_sigcleanup)
205 {
206 (*_rl_sigcleanup) (sig, _rl_sigcleanarg);
207 _rl_sigcleanup = 0;
208 _rl_sigcleanarg = 0;
209 }
210
Jari Aalto726f6381996-08-26 18:22:31 +0000211 switch (sig)
212 {
213 case SIGINT:
Jari Aalto31859422009-01-12 13:36:28 +0000214 _rl_reset_completion_state ();
Jari Aaltob72432f1999-02-19 17:11:39 +0000215 rl_free_line_state ();
216 /* FALLTHROUGH */
Jari Aalto726f6381996-08-26 18:22:31 +0000217
Jari Aalto95732b42005-12-07 14:08:12 +0000218 case SIGTERM:
Chet Rameyac50fba2014-02-26 09:36:43 -0500219 case SIGHUP:
Jari Aalto726f6381996-08-26 18:22:31 +0000220#if defined (SIGTSTP)
221 case SIGTSTP:
222 case SIGTTOU:
223 case SIGTTIN:
224#endif /* SIGTSTP */
Jari Aalto95732b42005-12-07 14:08:12 +0000225#if defined (SIGALRM)
Jari Aalto726f6381996-08-26 18:22:31 +0000226 case SIGALRM:
Jari Aalto95732b42005-12-07 14:08:12 +0000227#endif
228#if defined (SIGQUIT)
Jari Aaltob72432f1999-02-19 17:11:39 +0000229 case SIGQUIT:
Jari Aalto95732b42005-12-07 14:08:12 +0000230#endif
Jari Aalto31859422009-01-12 13:36:28 +0000231 rl_echo_signal_char (sig);
Jari Aaltob72432f1999-02-19 17:11:39 +0000232 rl_cleanup_after_signal ();
Jari Aalto726f6381996-08-26 18:22:31 +0000233
234#if defined (HAVE_POSIX_SIGNALS)
Jari Aalto06285672006-10-10 14:15:34 +0000235 sigemptyset (&set);
Jari Aalto726f6381996-08-26 18:22:31 +0000236 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
237 sigdelset (&set, sig);
238#else /* !HAVE_POSIX_SIGNALS */
239# if defined (HAVE_BSD_SIGNALS)
240 omask = sigblock (0);
241# endif /* HAVE_BSD_SIGNALS */
242#endif /* !HAVE_POSIX_SIGNALS */
243
Jari Aaltobb706242000-03-17 21:46:59 +0000244#if defined (__EMX__)
245 signal (sig, SIG_ACK);
246#endif
247
Jari Aalto95732b42005-12-07 14:08:12 +0000248#if defined (HAVE_KILL)
Jari Aalto726f6381996-08-26 18:22:31 +0000249 kill (getpid (), sig);
Jari Aalto95732b42005-12-07 14:08:12 +0000250#else
251 raise (sig); /* assume we have raise */
252#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000253
254 /* Let the signal that we just sent through. */
255#if defined (HAVE_POSIX_SIGNALS)
256 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
257#else /* !HAVE_POSIX_SIGNALS */
258# if defined (HAVE_BSD_SIGNALS)
259 sigsetmask (omask & ~(sigmask (sig)));
260# endif /* HAVE_BSD_SIGNALS */
261#endif /* !HAVE_POSIX_SIGNALS */
262
Chet Rameyac50fba2014-02-26 09:36:43 -0500263 rl_reset_after_signal ();
Jari Aalto726f6381996-08-26 18:22:31 +0000264 }
265
Jari Aalto28ef6c32001-04-06 19:14:31 +0000266 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000267 SIGHANDLER_RETURN;
Jari Aalto726f6381996-08-26 18:22:31 +0000268}
269
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000270#if defined (SIGWINCH)
271static RETSIGTYPE
Jari Aaltob72432f1999-02-19 17:11:39 +0000272rl_sigwinch_handler (sig)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000273 int sig;
274{
275 SigHandler *oh;
276
Jari Aaltod166f041997-06-05 14:59:13 +0000277#if defined (MUST_REINSTALL_SIGHANDLERS)
278 sighandler_cxt dummy_winch;
279
280 /* We don't want to change old_winch -- it holds the state of SIGWINCH
281 disposition set by the calling application. We need this state
282 because we call the application's SIGWINCH handler after updating
283 our own idea of the screen size. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000284 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
Jari Aaltod166f041997-06-05 14:59:13 +0000285#endif
286
Jari Aalto28ef6c32001-04-06 19:14:31 +0000287 RL_SETSTATE(RL_STATE_SIGHANDLER);
Chet Rameyac50fba2014-02-26 09:36:43 -0500288 _rl_caught_signal = sig;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000289
290 /* If another sigwinch handler has been installed, call it. */
291 oh = (SigHandler *)old_winch.sa_handler;
292 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
293 (*oh) (sig);
294
Jari Aalto28ef6c32001-04-06 19:14:31 +0000295 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000296 SIGHANDLER_RETURN;
297}
298#endif /* SIGWINCH */
299
300/* Functions to manage signal handling. */
301
302#if !defined (HAVE_POSIX_SIGNALS)
303static int
304rl_sigaction (sig, nh, oh)
305 int sig;
306 sighandler_cxt *nh, *oh;
307{
308 oh->sa_handler = signal (sig, nh->sa_handler);
309 return 0;
310}
311#endif /* !HAVE_POSIX_SIGNALS */
312
313/* Set up a readline-specific signal handler, saving the old signal
314 information in OHANDLER. Return the old signal handler, like
315 signal(). */
Jari Aalto726f6381996-08-26 18:22:31 +0000316static SigHandler *
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000317rl_set_sighandler (sig, handler, ohandler)
Jari Aalto726f6381996-08-26 18:22:31 +0000318 int sig;
319 SigHandler *handler;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000320 sighandler_cxt *ohandler;
Jari Aalto726f6381996-08-26 18:22:31 +0000321{
Jari Aaltobb706242000-03-17 21:46:59 +0000322 sighandler_cxt old_handler;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000323#if defined (HAVE_POSIX_SIGNALS)
324 struct sigaction act;
Jari Aalto726f6381996-08-26 18:22:31 +0000325
326 act.sa_handler = handler;
Jari Aalto31859422009-01-12 13:36:28 +0000327# if defined (SIGWINCH)
Jari Aaltob80f6442004-07-27 13:29:18 +0000328 act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
Jari Aalto31859422009-01-12 13:36:28 +0000329# else
330 act.sa_flags = 0;
331# endif /* SIGWINCH */
Jari Aalto726f6381996-08-26 18:22:31 +0000332 sigemptyset (&act.sa_mask);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000333 sigemptyset (&ohandler->sa_mask);
Jari Aaltobb706242000-03-17 21:46:59 +0000334 sigaction (sig, &act, &old_handler);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000335#else
Jari Aaltobb706242000-03-17 21:46:59 +0000336 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000337#endif /* !HAVE_POSIX_SIGNALS */
Jari Aaltobb706242000-03-17 21:46:59 +0000338
339 /* XXX -- assume we have memcpy */
340 /* If rl_set_signals is called twice in a row, don't set the old handler to
341 rl_signal_handler, because that would cause infinite recursion. */
342 if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
343 memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
344
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000345 return (ohandler->sa_handler);
Jari Aalto726f6381996-08-26 18:22:31 +0000346}
347
Chet Rameyac50fba2014-02-26 09:36:43 -0500348/* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't
349 change disposition if OHANDLER indicates the signal was ignored. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000350static void
351rl_maybe_set_sighandler (sig, handler, ohandler)
352 int sig;
353 SigHandler *handler;
354 sighandler_cxt *ohandler;
355{
356 sighandler_cxt dummy;
357 SigHandler *oh;
358
359 sigemptyset (&dummy.sa_mask);
Chet Rameyac50fba2014-02-26 09:36:43 -0500360 dummy.sa_flags = 0;
Jari Aaltob72432f1999-02-19 17:11:39 +0000361 oh = rl_set_sighandler (sig, handler, ohandler);
362 if (oh == (SigHandler *)SIG_IGN)
363 rl_sigaction (sig, ohandler, &dummy);
364}
365
Chet Rameyac50fba2014-02-26 09:36:43 -0500366/* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
367 signal was not being ignored. MUST only be called for signals whose
368 disposition was changed using rl_maybe_set_sighandler or for which the
369 SIG_IGN check was performed inline (e.g., SIGALRM below). */
370static void
371rl_maybe_restore_sighandler (sig, handler)
372 int sig;
373 sighandler_cxt *handler;
374{
375 sighandler_cxt dummy;
376
377 sigemptyset (&dummy.sa_mask);
378 dummy.sa_flags = 0;
379 if (handler->sa_handler != SIG_IGN)
380 rl_sigaction (sig, handler, &dummy);
381}
382
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000383int
Jari Aalto726f6381996-08-26 18:22:31 +0000384rl_set_signals ()
385{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000386 sighandler_cxt dummy;
387 SigHandler *oh;
Jari Aalto06285672006-10-10 14:15:34 +0000388#if defined (HAVE_POSIX_SIGNALS)
389 static int sigmask_set = 0;
390 static sigset_t bset, oset;
391#endif
392
393#if defined (HAVE_POSIX_SIGNALS)
394 if (rl_catch_signals && sigmask_set == 0)
395 {
396 sigemptyset (&bset);
397
398 sigaddset (&bset, SIGINT);
Jari Aalto31859422009-01-12 13:36:28 +0000399 sigaddset (&bset, SIGTERM);
Chet Rameyac50fba2014-02-26 09:36:43 -0500400 sigaddset (&bset, SIGHUP);
Jari Aalto06285672006-10-10 14:15:34 +0000401#if defined (SIGQUIT)
402 sigaddset (&bset, SIGQUIT);
403#endif
404#if defined (SIGALRM)
405 sigaddset (&bset, SIGALRM);
406#endif
407#if defined (SIGTSTP)
408 sigaddset (&bset, SIGTSTP);
409#endif
410#if defined (SIGTTIN)
411 sigaddset (&bset, SIGTTIN);
412#endif
413#if defined (SIGTTOU)
414 sigaddset (&bset, SIGTTOU);
415#endif
416 sigmask_set = 1;
417 }
418#endif /* HAVE_POSIX_SIGNALS */
Jari Aalto726f6381996-08-26 18:22:31 +0000419
Jari Aaltob72432f1999-02-19 17:11:39 +0000420 if (rl_catch_signals && signals_set_flag == 0)
421 {
Jari Aalto06285672006-10-10 14:15:34 +0000422#if defined (HAVE_POSIX_SIGNALS)
423 sigemptyset (&oset);
424 sigprocmask (SIG_BLOCK, &bset, &oset);
425#endif
426
Jari Aaltob72432f1999-02-19 17:11:39 +0000427 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
428 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
Chet Rameyac50fba2014-02-26 09:36:43 -0500429 rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
Jari Aalto95732b42005-12-07 14:08:12 +0000430#if defined (SIGQUIT)
Jari Aaltob72432f1999-02-19 17:11:39 +0000431 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
Jari Aalto95732b42005-12-07 14:08:12 +0000432#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000433
Jari Aalto95732b42005-12-07 14:08:12 +0000434#if defined (SIGALRM)
Jari Aaltob72432f1999-02-19 17:11:39 +0000435 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
436 if (oh == (SigHandler *)SIG_IGN)
437 rl_sigaction (SIGALRM, &old_alrm, &dummy);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000438#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
Jari Aaltob72432f1999-02-19 17:11:39 +0000439 /* If the application using readline has already installed a signal
440 handler with SA_RESTART, SIGALRM will cause reads to be restarted
441 automatically, so readline should just get out of the way. Since
442 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
443 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
444 rl_sigaction (SIGALRM, &old_alrm, &dummy);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000445#endif /* HAVE_POSIX_SIGNALS */
Jari Aalto95732b42005-12-07 14:08:12 +0000446#endif /* SIGALRM */
Jari Aalto726f6381996-08-26 18:22:31 +0000447
Jari Aalto726f6381996-08-26 18:22:31 +0000448#if defined (SIGTSTP)
Jari Aaltob72432f1999-02-19 17:11:39 +0000449 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
Jari Aalto726f6381996-08-26 18:22:31 +0000450#endif /* SIGTSTP */
Jari Aalto726f6381996-08-26 18:22:31 +0000451
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000452#if defined (SIGTTOU)
Jari Aaltob72432f1999-02-19 17:11:39 +0000453 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
Jari Aalto726f6381996-08-26 18:22:31 +0000454#endif /* SIGTTOU */
455
Jari Aaltob72432f1999-02-19 17:11:39 +0000456#if defined (SIGTTIN)
457 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
458#endif /* SIGTTIN */
Jari Aaltod166f041997-06-05 14:59:13 +0000459
Jari Aaltob72432f1999-02-19 17:11:39 +0000460 signals_set_flag = 1;
Jari Aalto06285672006-10-10 14:15:34 +0000461
462#if defined (HAVE_POSIX_SIGNALS)
463 sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
464#endif
Jari Aaltob72432f1999-02-19 17:11:39 +0000465 }
Jari Aalto726f6381996-08-26 18:22:31 +0000466
467#if defined (SIGWINCH)
Jari Aaltob72432f1999-02-19 17:11:39 +0000468 if (rl_catch_sigwinch && sigwinch_set_flag == 0)
469 {
470 rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
471 sigwinch_set_flag = 1;
472 }
Jari Aalto726f6381996-08-26 18:22:31 +0000473#endif /* SIGWINCH */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000474
Jari Aalto726f6381996-08-26 18:22:31 +0000475 return 0;
476}
477
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000478int
Jari Aalto726f6381996-08-26 18:22:31 +0000479rl_clear_signals ()
480{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000481 sighandler_cxt dummy;
482
Jari Aaltob72432f1999-02-19 17:11:39 +0000483 if (rl_catch_signals && signals_set_flag == 1)
484 {
485 sigemptyset (&dummy.sa_mask);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000486
Chet Rameyac50fba2014-02-26 09:36:43 -0500487 /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
488 we should in theory not have to restore a handler where
489 old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler
490 does. Fewer system calls should reduce readline's per-line
491 overhead */
492 rl_maybe_restore_sighandler (SIGINT, &old_int);
493 rl_maybe_restore_sighandler (SIGTERM, &old_term);
494 rl_maybe_restore_sighandler (SIGHUP, &old_hup);
Jari Aalto95732b42005-12-07 14:08:12 +0000495#if defined (SIGQUIT)
Chet Rameyac50fba2014-02-26 09:36:43 -0500496 rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
Jari Aalto95732b42005-12-07 14:08:12 +0000497#endif
498#if defined (SIGALRM)
Chet Rameyac50fba2014-02-26 09:36:43 -0500499 rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
Jari Aalto95732b42005-12-07 14:08:12 +0000500#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000501
502#if defined (SIGTSTP)
Chet Rameyac50fba2014-02-26 09:36:43 -0500503 rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
Jari Aaltob72432f1999-02-19 17:11:39 +0000504#endif /* SIGTSTP */
Jari Aalto726f6381996-08-26 18:22:31 +0000505
506#if defined (SIGTTOU)
Chet Rameyac50fba2014-02-26 09:36:43 -0500507 rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
Jari Aalto726f6381996-08-26 18:22:31 +0000508#endif /* SIGTTOU */
509
Jari Aaltob72432f1999-02-19 17:11:39 +0000510#if defined (SIGTTIN)
Chet Rameyac50fba2014-02-26 09:36:43 -0500511 rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
Jari Aaltob72432f1999-02-19 17:11:39 +0000512#endif /* SIGTTIN */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000513
Jari Aaltob72432f1999-02-19 17:11:39 +0000514 signals_set_flag = 0;
515 }
Jari Aalto726f6381996-08-26 18:22:31 +0000516
517#if defined (SIGWINCH)
Jari Aaltob72432f1999-02-19 17:11:39 +0000518 if (rl_catch_sigwinch && sigwinch_set_flag == 1)
519 {
520 sigemptyset (&dummy.sa_mask);
521 rl_sigaction (SIGWINCH, &old_winch, &dummy);
522 sigwinch_set_flag = 0;
523 }
Jari Aalto726f6381996-08-26 18:22:31 +0000524#endif
525
526 return 0;
527}
Jari Aaltob72432f1999-02-19 17:11:39 +0000528
529/* Clean up the terminal and readline state after catching a signal, before
530 resending it to the calling application. */
531void
532rl_cleanup_after_signal ()
533{
534 _rl_clean_up_for_exit ();
Jari Aalto95732b42005-12-07 14:08:12 +0000535 if (rl_deprep_term_function)
536 (*rl_deprep_term_function) ();
Jari Aalto28ef6c32001-04-06 19:14:31 +0000537 rl_clear_pending_input ();
Jari Aalto06285672006-10-10 14:15:34 +0000538 rl_clear_signals ();
Jari Aaltob72432f1999-02-19 17:11:39 +0000539}
540
541/* Reset the terminal and readline state after a signal handler returns. */
542void
543rl_reset_after_signal ()
544{
Jari Aalto95732b42005-12-07 14:08:12 +0000545 if (rl_prep_term_function)
546 (*rl_prep_term_function) (_rl_meta_flag);
Jari Aaltob72432f1999-02-19 17:11:39 +0000547 rl_set_signals ();
548}
549
550/* Free up the readline variable line state for the current line (undo list,
551 any partial history entry, any keyboard macros in progress, and any
552 numeric arguments in process) after catching a signal, before calling
553 rl_cleanup_after_signal(). */
554void
555rl_free_line_state ()
556{
557 register HIST_ENTRY *entry;
558
Jari Aalto28ef6c32001-04-06 19:14:31 +0000559 rl_free_undo_list ();
Jari Aaltob72432f1999-02-19 17:11:39 +0000560
561 entry = current_history ();
562 if (entry)
563 entry->data = (char *)NULL;
564
565 _rl_kill_kbd_macro ();
566 rl_clear_message ();
Jari Aalto95732b42005-12-07 14:08:12 +0000567 _rl_reset_argument ();
Jari Aaltob72432f1999-02-19 17:11:39 +0000568}
569
Jari Aalto726f6381996-08-26 18:22:31 +0000570#endif /* HANDLE_SIGNALS */
Jari Aalto31859422009-01-12 13:36:28 +0000571
572/* **************************************************************** */
573/* */
574/* SIGINT Management */
575/* */
576/* **************************************************************** */
577
578#if defined (HAVE_POSIX_SIGNALS)
579static sigset_t sigint_set, sigint_oset;
Chet Ramey00018032011-11-21 20:51:19 -0500580static sigset_t sigwinch_set, sigwinch_oset;
Jari Aalto31859422009-01-12 13:36:28 +0000581#else /* !HAVE_POSIX_SIGNALS */
582# if defined (HAVE_BSD_SIGNALS)
583static int sigint_oldmask;
Chet Ramey00018032011-11-21 20:51:19 -0500584static int sigwinch_oldmask;
Jari Aalto31859422009-01-12 13:36:28 +0000585# endif /* HAVE_BSD_SIGNALS */
586#endif /* !HAVE_POSIX_SIGNALS */
587
588static int sigint_blocked;
Chet Ramey00018032011-11-21 20:51:19 -0500589static int sigwinch_blocked;
Jari Aalto31859422009-01-12 13:36:28 +0000590
591/* Cause SIGINT to not be delivered until the corresponding call to
592 release_sigint(). */
593void
594_rl_block_sigint ()
595{
596 if (sigint_blocked)
597 return;
598
Jari Aalto31859422009-01-12 13:36:28 +0000599 sigint_blocked = 1;
600}
601
602/* Allow SIGINT to be delivered. */
603void
604_rl_release_sigint ()
605{
606 if (sigint_blocked == 0)
607 return;
608
Jari Aalto31859422009-01-12 13:36:28 +0000609 sigint_blocked = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -0500610 RL_CHECK_SIGNALS ();
Jari Aalto31859422009-01-12 13:36:28 +0000611}
612
Chet Ramey00018032011-11-21 20:51:19 -0500613/* Cause SIGWINCH to not be delivered until the corresponding call to
614 release_sigwinch(). */
615void
616_rl_block_sigwinch ()
617{
618 if (sigwinch_blocked)
619 return;
620
Chet Rameyac50fba2014-02-26 09:36:43 -0500621#if defined (SIGWINCH)
622
Chet Ramey00018032011-11-21 20:51:19 -0500623#if defined (HAVE_POSIX_SIGNALS)
624 sigemptyset (&sigwinch_set);
625 sigemptyset (&sigwinch_oset);
626 sigaddset (&sigwinch_set, SIGWINCH);
627 sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
628#else /* !HAVE_POSIX_SIGNALS */
629# if defined (HAVE_BSD_SIGNALS)
630 sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
631# else /* !HAVE_BSD_SIGNALS */
632# if defined (HAVE_USG_SIGHOLD)
633 sighold (SIGWINCH);
634# endif /* HAVE_USG_SIGHOLD */
635# endif /* !HAVE_BSD_SIGNALS */
636#endif /* !HAVE_POSIX_SIGNALS */
637
Chet Rameyac50fba2014-02-26 09:36:43 -0500638#endif /* SIGWINCH */
639
Chet Ramey00018032011-11-21 20:51:19 -0500640 sigwinch_blocked = 1;
641}
642
643/* Allow SIGWINCH to be delivered. */
644void
645_rl_release_sigwinch ()
646{
647 if (sigwinch_blocked == 0)
648 return;
649
Chet Rameyac50fba2014-02-26 09:36:43 -0500650#if defined (SIGWINCH)
651
Chet Ramey00018032011-11-21 20:51:19 -0500652#if defined (HAVE_POSIX_SIGNALS)
653 sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
654#else
655# if defined (HAVE_BSD_SIGNALS)
656 sigsetmask (sigwinch_oldmask);
657# else /* !HAVE_BSD_SIGNALS */
658# if defined (HAVE_USG_SIGHOLD)
659 sigrelse (SIGWINCH);
660# endif /* HAVE_USG_SIGHOLD */
661# endif /* !HAVE_BSD_SIGNALS */
662#endif /* !HAVE_POSIX_SIGNALS */
663
Chet Rameyac50fba2014-02-26 09:36:43 -0500664#endif /* SIGWINCH */
665
Chet Ramey00018032011-11-21 20:51:19 -0500666 sigwinch_blocked = 0;
667}
668
Jari Aalto31859422009-01-12 13:36:28 +0000669/* **************************************************************** */
670/* */
671/* Echoing special control characters */
672/* */
673/* **************************************************************** */
674void
675rl_echo_signal_char (sig)
676 int sig;
677{
678 char cstr[3];
679 int cslen, c;
680
Chet Ramey00018032011-11-21 20:51:19 -0500681 if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
Jari Aalto31859422009-01-12 13:36:28 +0000682 return;
683
684 switch (sig)
685 {
686 case SIGINT: c = _rl_intr_char; break;
Chet Ramey00018032011-11-21 20:51:19 -0500687#if defined (SIGQUIT)
Jari Aalto31859422009-01-12 13:36:28 +0000688 case SIGQUIT: c = _rl_quit_char; break;
Chet Ramey00018032011-11-21 20:51:19 -0500689#endif
690#if defined (SIGTSTP)
Jari Aalto31859422009-01-12 13:36:28 +0000691 case SIGTSTP: c = _rl_susp_char; break;
Chet Ramey00018032011-11-21 20:51:19 -0500692#endif
Jari Aalto31859422009-01-12 13:36:28 +0000693 default: return;
694 }
695
696 if (CTRL_CHAR (c) || c == RUBOUT)
697 {
698 cstr[0] = '^';
699 cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
700 cstr[cslen = 2] = '\0';
701 }
702 else
703 {
704 cstr[0] = c;
705 cstr[cslen = 1] = '\0';
706 }
707
708 _rl_output_some_chars (cstr, cslen);
709}