]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/readline/signals.c
bash-5.1 beta release
[thirdparty/bash.git] / lib / 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 (block_sig)
270 sigprocmask (SIG_BLOCK, &set, &oset);
271
272 rl_echo_signal_char (sig);
273 rl_cleanup_after_signal ();
274
275 /* At this point, the application's signal handler, if any, is the
276 current handler. */
277
278 #if defined (HAVE_POSIX_SIGNALS)
279 /* Unblock any signal(s) blocked above */
280 if (block_sig)
281 sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL);
282 #endif
283
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. */
290 sigemptyset (&set);
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 */
298 #endif
299
300 #if defined (__EMX__)
301 signal (sig, SIG_ACK);
302 #endif
303
304 #if defined (HAVE_KILL)
305 kill (getpid (), sig);
306 #else
307 raise (sig); /* assume we have raise */
308 #endif
309
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. */
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 */
321 #endif
322
323 rl_reset_after_signal ();
324 }
325
326 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
327 SIGHANDLER_RETURN;
328 }
329
330 #if defined (SIGWINCH)
331 static RETSIGTYPE
332 rl_sigwinch_handler (int sig)
333 {
334 SigHandler *oh;
335
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. */
343 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
344 #endif
345
346 RL_SETSTATE(RL_STATE_SIGHANDLER);
347 _rl_caught_signal = sig;
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
354 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
355 SIGHANDLER_RETURN;
356 }
357 #endif /* SIGWINCH */
358
359 /* Functions to manage signal handling. */
360
361 #if !defined (HAVE_POSIX_SIGNALS)
362 static int
363 rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh)
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(). */
373 static SigHandler *
374 rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
375 {
376 sighandler_cxt old_handler;
377 #if defined (HAVE_POSIX_SIGNALS)
378 struct sigaction act;
379
380 act.sa_handler = handler;
381 # if defined (SIGWINCH)
382 act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
383 # else
384 act.sa_flags = 0;
385 # endif /* SIGWINCH */
386 sigemptyset (&act.sa_mask);
387 sigemptyset (&ohandler->sa_mask);
388 sigaction (sig, &act, &old_handler);
389 #else
390 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
391 #endif /* !HAVE_POSIX_SIGNALS */
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
399 return (ohandler->sa_handler);
400 }
401
402 /* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't
403 change disposition if OHANDLER indicates the signal was ignored. */
404 static void
405 rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
406 {
407 sighandler_cxt dummy;
408 SigHandler *oh;
409
410 sigemptyset (&dummy.sa_mask);
411 dummy.sa_flags = 0;
412 oh = rl_set_sighandler (sig, handler, ohandler);
413 if (oh == (SigHandler *)SIG_IGN)
414 rl_sigaction (sig, ohandler, &dummy);
415 }
416
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). */
421 static void
422 rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler)
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
432 int
433 rl_set_signals (void)
434 {
435 sighandler_cxt dummy;
436 SigHandler *oh;
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);
448 sigaddset (&bset, SIGTERM);
449 #if defined (SIGHUP)
450 sigaddset (&bset, SIGHUP);
451 #endif
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 */
470
471 if (rl_catch_signals && signals_set_flag == 0)
472 {
473 #if defined (HAVE_POSIX_SIGNALS)
474 sigemptyset (&_rl_orig_sigset);
475 sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset);
476 #endif
477
478 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
479 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
480 #if defined (SIGHUP)
481 rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
482 #endif
483 #if defined (SIGQUIT)
484 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
485 #endif
486
487 #if defined (SIGALRM)
488 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
489 if (oh == (SigHandler *)SIG_IGN)
490 rl_sigaction (SIGALRM, &old_alrm, &dummy);
491 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
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);
498 #endif /* HAVE_POSIX_SIGNALS */
499 #endif /* SIGALRM */
500
501 #if defined (SIGTSTP)
502 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
503 #endif /* SIGTSTP */
504
505 #if defined (SIGTTOU)
506 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
507 #endif /* SIGTTOU */
508
509 #if defined (SIGTTIN)
510 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
511 #endif /* SIGTTIN */
512
513 signals_set_flag = 1;
514
515 #if defined (HAVE_POSIX_SIGNALS)
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);
524 #endif
525 }
526
527 #if defined (SIGWINCH)
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 }
533 #endif /* SIGWINCH */
534
535 return 0;
536 }
537
538 int
539 rl_clear_signals (void)
540 {
541 sighandler_cxt dummy;
542
543 if (rl_catch_signals && signals_set_flag == 1)
544 {
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);
552 #if defined (SIGHUP)
553 rl_maybe_restore_sighandler (SIGHUP, &old_hup);
554 #endif
555 #if defined (SIGQUIT)
556 rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
557 #endif
558 #if defined (SIGALRM)
559 rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
560 #endif
561
562 #if defined (SIGTSTP)
563 rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
564 #endif /* SIGTSTP */
565
566 #if defined (SIGTTOU)
567 rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
568 #endif /* SIGTTOU */
569
570 #if defined (SIGTTIN)
571 rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
572 #endif /* SIGTTIN */
573
574 signals_set_flag = 0;
575 }
576
577 #if defined (SIGWINCH)
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 }
584 #endif
585
586 return 0;
587 }
588
589 /* Clean up the terminal and readline state after catching a signal, before
590 resending it to the calling application. */
591 void
592 rl_cleanup_after_signal (void)
593 {
594 _rl_clean_up_for_exit ();
595 if (rl_deprep_term_function)
596 (*rl_deprep_term_function) ();
597 rl_clear_pending_input ();
598 rl_clear_signals ();
599 }
600
601 /* Reset the terminal and readline state after a signal handler returns. */
602 void
603 rl_reset_after_signal (void)
604 {
605 if (rl_prep_term_function)
606 (*rl_prep_term_function) (_rl_meta_flag);
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(). */
614 void
615 rl_free_line_state (void)
616 {
617 register HIST_ENTRY *entry;
618
619 rl_free_undo_list ();
620
621 entry = current_history ();
622 if (entry)
623 entry->data = (char *)NULL;
624
625 _rl_kill_kbd_macro ();
626 rl_clear_message ();
627 _rl_reset_argument ();
628 }
629
630 int
631 rl_pending_signal (void)
632 {
633 return (_rl_caught_signal);
634 }
635
636 void
637 rl_check_signals (void)
638 {
639 RL_CHECK_SIGNALS ();
640 }
641 #endif /* HANDLE_SIGNALS */
642
643 /* **************************************************************** */
644 /* */
645 /* SIGINT Management */
646 /* */
647 /* **************************************************************** */
648
649 #if defined (HAVE_POSIX_SIGNALS)
650 static sigset_t sigint_set, sigint_oset;
651 static sigset_t sigwinch_set, sigwinch_oset;
652 #else /* !HAVE_POSIX_SIGNALS */
653 # if defined (HAVE_BSD_SIGNALS)
654 static int sigint_oldmask;
655 static int sigwinch_oldmask;
656 # endif /* HAVE_BSD_SIGNALS */
657 #endif /* !HAVE_POSIX_SIGNALS */
658
659 static int sigint_blocked;
660 static int sigwinch_blocked;
661
662 /* Cause SIGINT to not be delivered until the corresponding call to
663 release_sigint(). */
664 void
665 _rl_block_sigint (void)
666 {
667 if (sigint_blocked)
668 return;
669
670 sigint_blocked = 1;
671 }
672
673 /* Allow SIGINT to be delivered. */
674 void
675 _rl_release_sigint (void)
676 {
677 if (sigint_blocked == 0)
678 return;
679
680 sigint_blocked = 0;
681 RL_CHECK_SIGNALS ();
682 }
683
684 /* Cause SIGWINCH to not be delivered until the corresponding call to
685 release_sigwinch(). */
686 void
687 _rl_block_sigwinch (void)
688 {
689 if (sigwinch_blocked)
690 return;
691
692 #if defined (SIGWINCH)
693
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
709 #endif /* SIGWINCH */
710
711 sigwinch_blocked = 1;
712 }
713
714 /* Allow SIGWINCH to be delivered. */
715 void
716 _rl_release_sigwinch (void)
717 {
718 if (sigwinch_blocked == 0)
719 return;
720
721 #if defined (SIGWINCH)
722
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
735 #endif /* SIGWINCH */
736
737 sigwinch_blocked = 0;
738 }
739
740 /* **************************************************************** */
741 /* */
742 /* Echoing special control characters */
743 /* */
744 /* **************************************************************** */
745 void
746 rl_echo_signal_char (int sig)
747 {
748 char cstr[3];
749 int cslen, c;
750
751 if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
752 return;
753
754 switch (sig)
755 {
756 case SIGINT: c = _rl_intr_char; break;
757 #if defined (SIGQUIT)
758 case SIGQUIT: c = _rl_quit_char; break;
759 #endif
760 #if defined (SIGTSTP)
761 case SIGTSTP: c = _rl_susp_char; break;
762 #endif
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 }