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
_rl_signal_handler(int sig)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
rl_signal_handler(int sig)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
_rl_handle_signal(int sig)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
rl_sigwinch_handler(int sig)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
rl_sigaction(int sig,sighandler_cxt * nh,sighandler_cxt * oh)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 *
rl_set_sighandler(int sig,SigHandler * handler,sighandler_cxt * ohandler)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
rl_maybe_set_sighandler(int sig,SigHandler * handler,sighandler_cxt * ohandler)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
rl_maybe_restore_sighandler(int sig,sighandler_cxt * handler)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
rl_set_signals(void)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
rl_clear_signals(void)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
rl_cleanup_after_signal(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
rl_reset_after_signal(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
rl_free_line_state(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
rl_pending_signal(void)633 rl_pending_signal (void)
634 {
635   return (_rl_caught_signal);
636 }
637 
638 void
rl_check_signals(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
_rl_block_sigint(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
_rl_release_sigint(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
_rl_block_sigwinch(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
_rl_release_sigwinch(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
rl_echo_signal_char(int sig)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 }
782