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