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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>