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