]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/signals.c
bash-5.1 distribution sources and documentation
[thirdparty/bash.git] / lib / readline / signals.c
CommitLineData
726f6388
JA
1/* signals.c -- signal handling support for readline. */
2
d233b485 3/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
726f6388 4
3185942a
JA
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.
726f6388 7
3185942a
JA
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
726f6388
JA
11 (at your option) any later version.
12
3185942a
JA
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
726f6388
JA
16 GNU General Public License for more details.
17
3185942a
JA
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/>.
20*/
21
726f6388
JA
22#define READLINE_LIBRARY
23
ccc6cda3
JA
24#if defined (HAVE_CONFIG_H)
25# include <config.h>
26#endif
27
28#include <stdio.h> /* Just for NULL. Yuck. */
726f6388 29#include <sys/types.h>
726f6388
JA
30#include <signal.h>
31
32#if defined (HAVE_UNISTD_H)
33# include <unistd.h>
34#endif /* HAVE_UNISTD_H */
35
726f6388
JA
36/* 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
bb70624e
JA
47#include "rlprivate.h"
48
3185942a
JA
49#if defined (HANDLE_SIGNALS)
50
ccc6cda3
JA
51#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 */
726f6388
JA
58
59#if defined (VOID_SIGHANDLER)
ccc6cda3 60# define SIGHANDLER_RETURN return
726f6388 61#else
ccc6cda3
JA
62# define SIGHANDLER_RETURN return (0)
63#endif
726f6388 64
28ef6c31 65/* This typedef is equivalent to the one for Function; it allows us
726f6388 66 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
ccc6cda3 67typedef RETSIGTYPE SigHandler ();
726f6388 68
bb70624e
JA
69#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 */
b72432fd 76
b80f6443
JA
77#ifndef SA_RESTART
78# define SA_RESTART 0
79#endif
80
f73dda09 81static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
7117c2d2 82static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
ac50fbac 83static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *));
726f6388 84
17345e5a
JA
85static RETSIGTYPE rl_signal_handler PARAMS((int));
86static RETSIGTYPE _rl_handle_signal PARAMS((int));
87
b72432fd
JA
88/* Exported variables for use by applications. */
89
90/* If non-zero, readline will install its own signal handlers for
ac50fbac 91 SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
b72432fd
JA
92int 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;
b80f6443
JA
97#else
98int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
b72432fd
JA
99#endif
100
3185942a 101/* Private variables. */
17345e5a
JA
102int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
103
0001803f
CR
104/* If non-zero, print characters corresponding to received signals as long as
105 the user has indicated his desire to do so (_rl_echo_control_chars). */
3185942a
JA
106int _rl_echoctl = 0;
107
108int _rl_intr_char = 0;
109int _rl_quit_char = 0;
110int _rl_susp_char = 0;
111
b72432fd
JA
112static int signals_set_flag;
113static int sigwinch_set_flag;
114
d233b485
CR
115#if defined (HAVE_POSIX_SIGNALS)
116sigset_t _rl_orig_sigset;
117#endif /* !HAVE_POSIX_SIGNALS */
118
726f6388
JA
119/* **************************************************************** */
120/* */
121/* Signal Handling */
122/* */
123/* **************************************************************** */
124
ac50fbac 125static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit;
b72432fd 126#if defined (SIGTSTP)
d166f048 127static sighandler_cxt old_tstp, old_ttou, old_ttin;
d166f048 128#endif
ccc6cda3
JA
129#if defined (SIGWINCH)
130static sighandler_cxt old_winch;
131#endif
132
ac50fbac
CR
133_rl_sigcleanup_func_t *_rl_sigcleanup;
134void *_rl_sigcleanarg;
135
ccc6cda3
JA
136/* Readline signal handler functions. */
137
8868edaf 138/* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */
17345e5a 139RETSIGTYPE
d233b485 140_rl_signal_handler (int sig)
17345e5a
JA
141{
142 _rl_caught_signal = 0; /* XXX */
143
ac50fbac
CR
144#if defined (SIGWINCH)
145 if (sig == SIGWINCH)
146 {
8868edaf
CR
147 RL_SETSTATE(RL_STATE_SIGHANDLER);
148
ac50fbac
CR
149 rl_resize_terminal ();
150 /* XXX - experimental for now */
151 /* Call a signal hook because though we called the original signal handler
152 in rl_sigwinch_handler below, we will not resend the signal to
153 ourselves. */
154 if (rl_signal_event_hook)
155 (*rl_signal_event_hook) ();
8868edaf
CR
156
157 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
ac50fbac
CR
158 }
159 else
160#endif
161 _rl_handle_signal (sig);
162
17345e5a
JA
163 SIGHANDLER_RETURN;
164}
165
ccc6cda3 166static RETSIGTYPE
d233b485 167rl_signal_handler (int sig)
17345e5a 168{
8868edaf 169 _rl_caught_signal = sig;
17345e5a
JA
170 SIGHANDLER_RETURN;
171}
172
8868edaf
CR
173/* This is called to handle a signal when it is safe to do so (out of the
174 signal handler execution path). Called by _rl_signal_handler for all the
175 signals readline catches except SIGWINCH. */
17345e5a 176static RETSIGTYPE
d233b485 177_rl_handle_signal (int sig)
726f6388 178{
8868edaf
CR
179 int block_sig;
180
726f6388 181#if defined (HAVE_POSIX_SIGNALS)
8868edaf 182 sigset_t set, oset;
726f6388
JA
183#else /* !HAVE_POSIX_SIGNALS */
184# if defined (HAVE_BSD_SIGNALS)
185 long omask;
d166f048
JA
186# else /* !HAVE_BSD_SIGNALS */
187 sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
188# endif /* !HAVE_BSD_SIGNALS */
726f6388
JA
189#endif /* !HAVE_POSIX_SIGNALS */
190
28ef6c31
JA
191 RL_SETSTATE(RL_STATE_SIGHANDLER);
192
726f6388
JA
193#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
194 /* Since the signal will not be blocked while we are in the signal
195 handler, ignore it until rl_clear_signals resets the catcher. */
95732b49 196# if defined (SIGALRM)
ccc6cda3 197 if (sig == SIGINT || sig == SIGALRM)
95732b49
JA
198# else
199 if (sig == SIGINT)
200# endif
d166f048 201 rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
ccc6cda3 202#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
726f6388 203
ac50fbac
CR
204 /* If there's a sig cleanup function registered, call it and `deregister'
205 the cleanup function to avoid multiple calls */
206 if (_rl_sigcleanup)
207 {
208 (*_rl_sigcleanup) (sig, _rl_sigcleanarg);
209 _rl_sigcleanup = 0;
210 _rl_sigcleanarg = 0;
211 }
8868edaf
CR
212
213#if defined (HAVE_POSIX_SIGNALS)
214 /* Get the current set of blocked signals. If we want to block a signal for
215 the duration of the cleanup functions, make sure to add it to SET and
216 set block_sig = 1 (see the SIGHUP case below). */
217 block_sig = 0; /* sentinel to block signals with sigprocmask */
218 sigemptyset (&set);
219 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
220#endif
221
726f6388
JA
222 switch (sig)
223 {
224 case SIGINT:
3185942a 225 _rl_reset_completion_state ();
b72432fd 226 rl_free_line_state ();
a0c0a00f
CR
227#if defined (READLINE_CALLBACKS)
228 rl_callback_sigcleanup ();
229#endif
230
b72432fd 231 /* FALLTHROUGH */
726f6388
JA
232
233#if defined (SIGTSTP)
234 case SIGTSTP:
726f6388 235 case SIGTTIN:
8868edaf 236 case SIGTTOU:
a0c0a00f
CR
237# if defined (HAVE_POSIX_SIGNALS)
238 /* Block SIGTTOU so we can restore the terminal settings to something
239 sane without stopping on SIGTTOU if we have been placed into the
240 background. Even trying to get the current terminal pgrp with
8868edaf
CR
241 tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do
242 this even if we've been stopped on SIGTTOU, since we handle signals
243 when we have returned from the signal handler and the signal is no
244 longer blocked. */
a0c0a00f 245 sigaddset (&set, SIGTTOU);
8868edaf 246 block_sig = 1;
a0c0a00f 247# endif
726f6388 248#endif /* SIGTSTP */
8868edaf 249 /* Any signals that should be blocked during cleanup should go here. */
a0c0a00f
CR
250#if defined (SIGHUP)
251 case SIGHUP:
8868edaf
CR
252# if defined (_AIX)
253 if (block_sig == 0)
254 {
255 sigaddset (&set, sig);
256 block_sig = 1;
257 }
258# endif // _AIX
a0c0a00f 259#endif
8868edaf
CR
260 /* Signals that don't require blocking during cleanup should go here. */
261 case SIGTERM:
95732b49 262#if defined (SIGALRM)
726f6388 263 case SIGALRM:
95732b49
JA
264#endif
265#if defined (SIGQUIT)
b72432fd 266 case SIGQUIT:
95732b49 267#endif
8868edaf
CR
268
269 if (block_sig)
270 sigprocmask (SIG_BLOCK, &set, &oset);
271
3185942a 272 rl_echo_signal_char (sig);
b72432fd 273 rl_cleanup_after_signal ();
726f6388 274
8868edaf
CR
275 /* At this point, the application's signal handler, if any, is the
276 current handler. */
277
726f6388 278#if defined (HAVE_POSIX_SIGNALS)
8868edaf
CR
279 /* Unblock any signal(s) blocked above */
280 if (block_sig)
281 sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL);
282#endif
a0c0a00f 283
8868edaf
CR
284 /* We don't have to bother unblocking the signal because we are not
285 running in a signal handler context. */
286#if 0
287#if defined (HAVE_POSIX_SIGNALS)
288 /* Make sure this signal is not blocked when we resend it to the
289 calling application. */
0628567a 290 sigemptyset (&set);
726f6388
JA
291 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
292 sigdelset (&set, sig);
293#else /* !HAVE_POSIX_SIGNALS */
294# if defined (HAVE_BSD_SIGNALS)
295 omask = sigblock (0);
296# endif /* HAVE_BSD_SIGNALS */
297#endif /* !HAVE_POSIX_SIGNALS */
8868edaf 298#endif
726f6388 299
bb70624e
JA
300#if defined (__EMX__)
301 signal (sig, SIG_ACK);
302#endif
303
95732b49 304#if defined (HAVE_KILL)
726f6388 305 kill (getpid (), sig);
95732b49
JA
306#else
307 raise (sig); /* assume we have raise */
308#endif
726f6388 309
8868edaf
CR
310 /* We don't need to modify the signal mask now that this is not run in
311 a signal handler context. */
312#if 0
313 /* Let the signal that we just sent through if it is blocked. */
726f6388
JA
314#if defined (HAVE_POSIX_SIGNALS)
315 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
316#else /* !HAVE_POSIX_SIGNALS */
317# if defined (HAVE_BSD_SIGNALS)
318 sigsetmask (omask & ~(sigmask (sig)));
319# endif /* HAVE_BSD_SIGNALS */
320#endif /* !HAVE_POSIX_SIGNALS */
8868edaf 321#endif
726f6388 322
ac50fbac 323 rl_reset_after_signal ();
726f6388
JA
324 }
325
28ef6c31 326 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
ccc6cda3 327 SIGHANDLER_RETURN;
726f6388
JA
328}
329
ccc6cda3
JA
330#if defined (SIGWINCH)
331static RETSIGTYPE
d233b485 332rl_sigwinch_handler (int sig)
ccc6cda3
JA
333{
334 SigHandler *oh;
335
d166f048
JA
336#if defined (MUST_REINSTALL_SIGHANDLERS)
337 sighandler_cxt dummy_winch;
338
339 /* We don't want to change old_winch -- it holds the state of SIGWINCH
340 disposition set by the calling application. We need this state
341 because we call the application's SIGWINCH handler after updating
342 our own idea of the screen size. */
b72432fd 343 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
d166f048
JA
344#endif
345
28ef6c31 346 RL_SETSTATE(RL_STATE_SIGHANDLER);
ac50fbac 347 _rl_caught_signal = sig;
ccc6cda3
JA
348
349 /* If another sigwinch handler has been installed, call it. */
350 oh = (SigHandler *)old_winch.sa_handler;
351 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
352 (*oh) (sig);
353
28ef6c31 354 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
ccc6cda3
JA
355 SIGHANDLER_RETURN;
356}
357#endif /* SIGWINCH */
358
359/* Functions to manage signal handling. */
360
361#if !defined (HAVE_POSIX_SIGNALS)
362static int
d233b485 363rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh)
ccc6cda3
JA
364{
365 oh->sa_handler = signal (sig, nh->sa_handler);
366 return 0;
367}
368#endif /* !HAVE_POSIX_SIGNALS */
369
370/* Set up a readline-specific signal handler, saving the old signal
371 information in OHANDLER. Return the old signal handler, like
372 signal(). */
726f6388 373static SigHandler *
d233b485 374rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
726f6388 375{
bb70624e 376 sighandler_cxt old_handler;
ccc6cda3
JA
377#if defined (HAVE_POSIX_SIGNALS)
378 struct sigaction act;
726f6388
JA
379
380 act.sa_handler = handler;
3185942a 381# if defined (SIGWINCH)
b80f6443 382 act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
3185942a
JA
383# else
384 act.sa_flags = 0;
385# endif /* SIGWINCH */
726f6388 386 sigemptyset (&act.sa_mask);
ccc6cda3 387 sigemptyset (&ohandler->sa_mask);
bb70624e 388 sigaction (sig, &act, &old_handler);
ccc6cda3 389#else
bb70624e 390 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
726f6388 391#endif /* !HAVE_POSIX_SIGNALS */
bb70624e
JA
392
393 /* XXX -- assume we have memcpy */
394 /* If rl_set_signals is called twice in a row, don't set the old handler to
395 rl_signal_handler, because that would cause infinite recursion. */
396 if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
397 memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
398
ccc6cda3
JA
399 return (ohandler->sa_handler);
400}
726f6388 401
ac50fbac
CR
402/* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't
403 change disposition if OHANDLER indicates the signal was ignored. */
b72432fd 404static void
d233b485 405rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
726f6388 406{
ccc6cda3
JA
407 sighandler_cxt dummy;
408 SigHandler *oh;
409
ccc6cda3 410 sigemptyset (&dummy.sa_mask);
ac50fbac 411 dummy.sa_flags = 0;
b72432fd 412 oh = rl_set_sighandler (sig, handler, ohandler);
ccc6cda3 413 if (oh == (SigHandler *)SIG_IGN)
b72432fd
JA
414 rl_sigaction (sig, ohandler, &dummy);
415}
ccc6cda3 416
ac50fbac
CR
417/* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
418 signal was not being ignored. MUST only be called for signals whose
419 disposition was changed using rl_maybe_set_sighandler or for which the
420 SIG_IGN check was performed inline (e.g., SIGALRM below). */
421static void
d233b485 422rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler)
ac50fbac
CR
423{
424 sighandler_cxt dummy;
425
426 sigemptyset (&dummy.sa_mask);
427 dummy.sa_flags = 0;
428 if (handler->sa_handler != SIG_IGN)
429 rl_sigaction (sig, handler, &dummy);
430}
431
b72432fd 432int
d233b485 433rl_set_signals (void)
b72432fd
JA
434{
435 sighandler_cxt dummy;
436 SigHandler *oh;
0628567a
JA
437#if defined (HAVE_POSIX_SIGNALS)
438 static int sigmask_set = 0;
439 static sigset_t bset, oset;
440#endif
441
442#if defined (HAVE_POSIX_SIGNALS)
443 if (rl_catch_signals && sigmask_set == 0)
444 {
445 sigemptyset (&bset);
446
447 sigaddset (&bset, SIGINT);
3185942a 448 sigaddset (&bset, SIGTERM);
a0c0a00f 449#if defined (SIGHUP)
ac50fbac 450 sigaddset (&bset, SIGHUP);
a0c0a00f 451#endif
0628567a
JA
452#if defined (SIGQUIT)
453 sigaddset (&bset, SIGQUIT);
454#endif
455#if defined (SIGALRM)
456 sigaddset (&bset, SIGALRM);
457#endif
458#if defined (SIGTSTP)
459 sigaddset (&bset, SIGTSTP);
460#endif
461#if defined (SIGTTIN)
462 sigaddset (&bset, SIGTTIN);
463#endif
464#if defined (SIGTTOU)
465 sigaddset (&bset, SIGTTOU);
466#endif
467 sigmask_set = 1;
468 }
469#endif /* HAVE_POSIX_SIGNALS */
b72432fd
JA
470
471 if (rl_catch_signals && signals_set_flag == 0)
472 {
0628567a 473#if defined (HAVE_POSIX_SIGNALS)
d233b485
CR
474 sigemptyset (&_rl_orig_sigset);
475 sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset);
0628567a
JA
476#endif
477
b72432fd
JA
478 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
479 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
a0c0a00f 480#if defined (SIGHUP)
ac50fbac 481 rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
a0c0a00f 482#endif
95732b49 483#if defined (SIGQUIT)
b72432fd 484 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
95732b49 485#endif
b72432fd 486
95732b49 487#if defined (SIGALRM)
b72432fd
JA
488 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
489 if (oh == (SigHandler *)SIG_IGN)
490 rl_sigaction (SIGALRM, &old_alrm, &dummy);
ccc6cda3 491#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
b72432fd
JA
492 /* If the application using readline has already installed a signal
493 handler with SA_RESTART, SIGALRM will cause reads to be restarted
494 automatically, so readline should just get out of the way. Since
495 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
496 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
497 rl_sigaction (SIGALRM, &old_alrm, &dummy);
ccc6cda3 498#endif /* HAVE_POSIX_SIGNALS */
95732b49 499#endif /* SIGALRM */
726f6388 500
726f6388 501#if defined (SIGTSTP)
b72432fd 502 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
726f6388 503#endif /* SIGTSTP */
ccc6cda3 504
726f6388 505#if defined (SIGTTOU)
b72432fd 506 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
726f6388
JA
507#endif /* SIGTTOU */
508
b72432fd
JA
509#if defined (SIGTTIN)
510 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
511#endif /* SIGTTIN */
d166f048 512
b72432fd 513 signals_set_flag = 1;
0628567a
JA
514
515#if defined (HAVE_POSIX_SIGNALS)
d233b485
CR
516 sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL);
517#endif
518 }
519 else if (rl_catch_signals == 0)
520 {
521#if defined (HAVE_POSIX_SIGNALS)
522 sigemptyset (&_rl_orig_sigset);
523 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset);
0628567a 524#endif
b72432fd 525 }
726f6388
JA
526
527#if defined (SIGWINCH)
b72432fd
JA
528 if (rl_catch_sigwinch && sigwinch_set_flag == 0)
529 {
530 rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
531 sigwinch_set_flag = 1;
532 }
726f6388 533#endif /* SIGWINCH */
ccc6cda3 534
726f6388
JA
535 return 0;
536}
537
ccc6cda3 538int
d233b485 539rl_clear_signals (void)
726f6388 540{
ccc6cda3
JA
541 sighandler_cxt dummy;
542
b72432fd
JA
543 if (rl_catch_signals && signals_set_flag == 1)
544 {
ac50fbac
CR
545 /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
546 we should in theory not have to restore a handler where
547 old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler
548 does. Fewer system calls should reduce readline's per-line
549 overhead */
550 rl_maybe_restore_sighandler (SIGINT, &old_int);
551 rl_maybe_restore_sighandler (SIGTERM, &old_term);
a0c0a00f 552#if defined (SIGHUP)
ac50fbac 553 rl_maybe_restore_sighandler (SIGHUP, &old_hup);
a0c0a00f 554#endif
95732b49 555#if defined (SIGQUIT)
ac50fbac 556 rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
95732b49
JA
557#endif
558#if defined (SIGALRM)
ac50fbac 559 rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
95732b49 560#endif
726f6388
JA
561
562#if defined (SIGTSTP)
ac50fbac 563 rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
b72432fd 564#endif /* SIGTSTP */
726f6388
JA
565
566#if defined (SIGTTOU)
ac50fbac 567 rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
726f6388
JA
568#endif /* SIGTTOU */
569
b72432fd 570#if defined (SIGTTIN)
ac50fbac 571 rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
b72432fd 572#endif /* SIGTTIN */
ccc6cda3 573
b72432fd
JA
574 signals_set_flag = 0;
575 }
726f6388
JA
576
577#if defined (SIGWINCH)
b72432fd
JA
578 if (rl_catch_sigwinch && sigwinch_set_flag == 1)
579 {
580 sigemptyset (&dummy.sa_mask);
581 rl_sigaction (SIGWINCH, &old_winch, &dummy);
582 sigwinch_set_flag = 0;
583 }
726f6388
JA
584#endif
585
586 return 0;
587}
b72432fd
JA
588
589/* Clean up the terminal and readline state after catching a signal, before
590 resending it to the calling application. */
591void
d233b485 592rl_cleanup_after_signal (void)
b72432fd
JA
593{
594 _rl_clean_up_for_exit ();
95732b49
JA
595 if (rl_deprep_term_function)
596 (*rl_deprep_term_function) ();
28ef6c31 597 rl_clear_pending_input ();
0628567a 598 rl_clear_signals ();
b72432fd
JA
599}
600
601/* Reset the terminal and readline state after a signal handler returns. */
602void
d233b485 603rl_reset_after_signal (void)
b72432fd 604{
95732b49
JA
605 if (rl_prep_term_function)
606 (*rl_prep_term_function) (_rl_meta_flag);
b72432fd
JA
607 rl_set_signals ();
608}
609
610/* Free up the readline variable line state for the current line (undo list,
611 any partial history entry, any keyboard macros in progress, and any
612 numeric arguments in process) after catching a signal, before calling
613 rl_cleanup_after_signal(). */
614void
d233b485 615rl_free_line_state (void)
b72432fd
JA
616{
617 register HIST_ENTRY *entry;
618
28ef6c31 619 rl_free_undo_list ();
b72432fd
JA
620
621 entry = current_history ();
622 if (entry)
623 entry->data = (char *)NULL;
624
625 _rl_kill_kbd_macro ();
626 rl_clear_message ();
95732b49 627 _rl_reset_argument ();
b72432fd
JA
628}
629
a0c0a00f 630int
d233b485 631rl_pending_signal (void)
a0c0a00f
CR
632{
633 return (_rl_caught_signal);
634}
d233b485
CR
635
636void
637rl_check_signals (void)
638{
639 RL_CHECK_SIGNALS ();
640}
726f6388 641#endif /* HANDLE_SIGNALS */
3185942a
JA
642
643/* **************************************************************** */
644/* */
645/* SIGINT Management */
646/* */
647/* **************************************************************** */
648
649#if defined (HAVE_POSIX_SIGNALS)
650static sigset_t sigint_set, sigint_oset;
0001803f 651static sigset_t sigwinch_set, sigwinch_oset;
3185942a
JA
652#else /* !HAVE_POSIX_SIGNALS */
653# if defined (HAVE_BSD_SIGNALS)
654static int sigint_oldmask;
0001803f 655static int sigwinch_oldmask;
3185942a
JA
656# endif /* HAVE_BSD_SIGNALS */
657#endif /* !HAVE_POSIX_SIGNALS */
658
659static int sigint_blocked;
0001803f 660static int sigwinch_blocked;
3185942a
JA
661
662/* Cause SIGINT to not be delivered until the corresponding call to
663 release_sigint(). */
664void
d233b485 665_rl_block_sigint (void)
3185942a
JA
666{
667 if (sigint_blocked)
668 return;
669
3185942a
JA
670 sigint_blocked = 1;
671}
672
673/* Allow SIGINT to be delivered. */
674void
d233b485 675_rl_release_sigint (void)
3185942a
JA
676{
677 if (sigint_blocked == 0)
678 return;
679
3185942a 680 sigint_blocked = 0;
ac50fbac 681 RL_CHECK_SIGNALS ();
3185942a
JA
682}
683
0001803f
CR
684/* Cause SIGWINCH to not be delivered until the corresponding call to
685 release_sigwinch(). */
686void
d233b485 687_rl_block_sigwinch (void)
0001803f
CR
688{
689 if (sigwinch_blocked)
690 return;
691
ac50fbac
CR
692#if defined (SIGWINCH)
693
0001803f
CR
694#if defined (HAVE_POSIX_SIGNALS)
695 sigemptyset (&sigwinch_set);
696 sigemptyset (&sigwinch_oset);
697 sigaddset (&sigwinch_set, SIGWINCH);
698 sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
699#else /* !HAVE_POSIX_SIGNALS */
700# if defined (HAVE_BSD_SIGNALS)
701 sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
702# else /* !HAVE_BSD_SIGNALS */
703# if defined (HAVE_USG_SIGHOLD)
704 sighold (SIGWINCH);
705# endif /* HAVE_USG_SIGHOLD */
706# endif /* !HAVE_BSD_SIGNALS */
707#endif /* !HAVE_POSIX_SIGNALS */
708
ac50fbac
CR
709#endif /* SIGWINCH */
710
0001803f
CR
711 sigwinch_blocked = 1;
712}
713
714/* Allow SIGWINCH to be delivered. */
715void
d233b485 716_rl_release_sigwinch (void)
0001803f
CR
717{
718 if (sigwinch_blocked == 0)
719 return;
720
ac50fbac
CR
721#if defined (SIGWINCH)
722
0001803f
CR
723#if defined (HAVE_POSIX_SIGNALS)
724 sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
725#else
726# if defined (HAVE_BSD_SIGNALS)
727 sigsetmask (sigwinch_oldmask);
728# else /* !HAVE_BSD_SIGNALS */
729# if defined (HAVE_USG_SIGHOLD)
730 sigrelse (SIGWINCH);
731# endif /* HAVE_USG_SIGHOLD */
732# endif /* !HAVE_BSD_SIGNALS */
733#endif /* !HAVE_POSIX_SIGNALS */
734
ac50fbac
CR
735#endif /* SIGWINCH */
736
0001803f
CR
737 sigwinch_blocked = 0;
738}
739
3185942a
JA
740/* **************************************************************** */
741/* */
742/* Echoing special control characters */
743/* */
744/* **************************************************************** */
745void
d233b485 746rl_echo_signal_char (int sig)
3185942a
JA
747{
748 char cstr[3];
749 int cslen, c;
750
0001803f 751 if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
3185942a
JA
752 return;
753
754 switch (sig)
755 {
756 case SIGINT: c = _rl_intr_char; break;
0001803f 757#if defined (SIGQUIT)
3185942a 758 case SIGQUIT: c = _rl_quit_char; break;
0001803f
CR
759#endif
760#if defined (SIGTSTP)
3185942a 761 case SIGTSTP: c = _rl_susp_char; break;
0001803f 762#endif
3185942a
JA
763 default: return;
764 }
765
766 if (CTRL_CHAR (c) || c == RUBOUT)
767 {
768 cstr[0] = '^';
769 cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
770 cstr[cslen = 2] = '\0';
771 }
772 else
773 {
774 cstr[0] = c;
775 cstr[cslen = 1] = '\0';
776 }
777
778 _rl_output_some_chars (cstr, cslen);
779}