xref: /dflybsd-src/contrib/gdb-7/readline/signals.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
16b445a62SJohn Marino /* signals.c -- signal handling support for readline. */
26b445a62SJohn Marino 
36b445a62SJohn Marino /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
46b445a62SJohn Marino 
56b445a62SJohn Marino    This file is part of the GNU Readline Library (Readline), a library
66b445a62SJohn Marino    for reading lines of text with interactive input and history editing.
76b445a62SJohn Marino 
86b445a62SJohn Marino    Readline is free software: you can redistribute it and/or modify
96b445a62SJohn Marino    it under the terms of the GNU General Public License as published by
106b445a62SJohn Marino    the Free Software Foundation, either version 3 of the License, or
116b445a62SJohn Marino    (at your option) any later version.
126b445a62SJohn Marino 
136b445a62SJohn Marino    Readline is distributed in the hope that it will be useful,
146b445a62SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
156b445a62SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
166b445a62SJohn Marino    GNU General Public License for more details.
176b445a62SJohn Marino 
186b445a62SJohn Marino    You should have received a copy of the GNU General Public License
196b445a62SJohn Marino    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
206b445a62SJohn Marino */
216b445a62SJohn Marino 
226b445a62SJohn Marino #define READLINE_LIBRARY
236b445a62SJohn Marino 
246b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
256b445a62SJohn Marino #  include <config.h>
266b445a62SJohn Marino #endif
276b445a62SJohn Marino 
286b445a62SJohn Marino #include <stdio.h>		/* Just for NULL.  Yuck. */
296b445a62SJohn Marino #include <sys/types.h>
306b445a62SJohn Marino #include <signal.h>
316b445a62SJohn Marino 
326b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
336b445a62SJohn Marino #  include <unistd.h>
346b445a62SJohn Marino #endif /* HAVE_UNISTD_H */
356b445a62SJohn Marino 
366b445a62SJohn Marino /* System-specific feature definitions and include files. */
376b445a62SJohn Marino #include "rldefs.h"
386b445a62SJohn Marino 
396b445a62SJohn Marino #if defined (GWINSZ_IN_SYS_IOCTL)
406b445a62SJohn Marino #  include <sys/ioctl.h>
416b445a62SJohn Marino #endif /* GWINSZ_IN_SYS_IOCTL */
426b445a62SJohn Marino 
436b445a62SJohn Marino /* Some standard library routines. */
446b445a62SJohn Marino #include "readline.h"
456b445a62SJohn Marino #include "history.h"
466b445a62SJohn Marino 
476b445a62SJohn Marino #include "rlprivate.h"
486b445a62SJohn Marino 
496b445a62SJohn Marino #if defined (HANDLE_SIGNALS)
506b445a62SJohn Marino 
516b445a62SJohn Marino #if !defined (RETSIGTYPE)
526b445a62SJohn Marino #  if defined (VOID_SIGHANDLER)
536b445a62SJohn Marino #    define RETSIGTYPE void
546b445a62SJohn Marino #  else
556b445a62SJohn Marino #    define RETSIGTYPE int
566b445a62SJohn Marino #  endif /* !VOID_SIGHANDLER */
576b445a62SJohn Marino #endif /* !RETSIGTYPE */
586b445a62SJohn Marino 
596b445a62SJohn Marino #if defined (VOID_SIGHANDLER)
606b445a62SJohn Marino #  define SIGHANDLER_RETURN return
616b445a62SJohn Marino #else
626b445a62SJohn Marino #  define SIGHANDLER_RETURN return (0)
636b445a62SJohn Marino #endif
646b445a62SJohn Marino 
656b445a62SJohn Marino /* This typedef is equivalent to the one for Function; it allows us
666b445a62SJohn Marino    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
676b445a62SJohn Marino typedef RETSIGTYPE SigHandler ();
686b445a62SJohn Marino 
696b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
706b445a62SJohn Marino typedef struct sigaction sighandler_cxt;
716b445a62SJohn Marino #  define rl_sigaction(s, nh, oh)	sigaction(s, nh, oh)
726b445a62SJohn Marino #else
736b445a62SJohn Marino typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
746b445a62SJohn Marino #  define sigemptyset(m)
756b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
766b445a62SJohn Marino 
776b445a62SJohn Marino #ifndef SA_RESTART
786b445a62SJohn Marino #  define SA_RESTART 0
796b445a62SJohn Marino #endif
806b445a62SJohn Marino 
816b445a62SJohn Marino static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
826b445a62SJohn Marino static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
836b445a62SJohn Marino 
846b445a62SJohn Marino static RETSIGTYPE rl_signal_handler PARAMS((int));
856b445a62SJohn Marino static RETSIGTYPE _rl_handle_signal PARAMS((int));
866b445a62SJohn Marino 
876b445a62SJohn Marino /* Exported variables for use by applications. */
886b445a62SJohn Marino 
896b445a62SJohn Marino /* If non-zero, readline will install its own signal handlers for
906b445a62SJohn Marino    SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
916b445a62SJohn Marino int rl_catch_signals = 1;
926b445a62SJohn Marino 
936b445a62SJohn Marino /* If non-zero, readline will install a signal handler for SIGWINCH. */
946b445a62SJohn Marino #ifdef SIGWINCH
956b445a62SJohn Marino int rl_catch_sigwinch = 1;
966b445a62SJohn Marino #else
976b445a62SJohn Marino int rl_catch_sigwinch = 0;	/* for the readline state struct in readline.c */
986b445a62SJohn Marino #endif
996b445a62SJohn Marino 
1006b445a62SJohn Marino /* Private variables. */
1016b445a62SJohn Marino int _rl_interrupt_immediately = 0;
1026b445a62SJohn Marino int volatile _rl_caught_signal = 0;	/* should be sig_atomic_t, but that requires including <signal.h> everywhere */
1036b445a62SJohn Marino 
1046b445a62SJohn Marino /* If non-zero, print characters corresponding to received signals as long as
1056b445a62SJohn Marino    the user has indicated his desire to do so (_rl_echo_control_chars). */
1066b445a62SJohn Marino int _rl_echoctl = 0;
1076b445a62SJohn Marino 
1086b445a62SJohn Marino int _rl_intr_char = 0;
1096b445a62SJohn Marino int _rl_quit_char = 0;
1106b445a62SJohn Marino int _rl_susp_char = 0;
1116b445a62SJohn Marino 
1126b445a62SJohn Marino static int signals_set_flag;
1136b445a62SJohn Marino static int sigwinch_set_flag;
1146b445a62SJohn Marino 
1156b445a62SJohn Marino /* **************************************************************** */
1166b445a62SJohn Marino /*					        		    */
1176b445a62SJohn Marino /*			   Signal Handling                          */
1186b445a62SJohn Marino /*								    */
1196b445a62SJohn Marino /* **************************************************************** */
1206b445a62SJohn Marino 
1216b445a62SJohn Marino static sighandler_cxt old_int, old_term, old_alrm, old_quit;
1226b445a62SJohn Marino #if defined (SIGTSTP)
1236b445a62SJohn Marino static sighandler_cxt old_tstp, old_ttou, old_ttin;
1246b445a62SJohn Marino #endif
1256b445a62SJohn Marino #if defined (SIGWINCH)
1266b445a62SJohn Marino static sighandler_cxt old_winch;
1276b445a62SJohn Marino #endif
1286b445a62SJohn Marino 
1296b445a62SJohn Marino /* Readline signal handler functions. */
1306b445a62SJohn Marino 
1316b445a62SJohn Marino /* Called from RL_CHECK_SIGNALS() macro */
1326b445a62SJohn Marino RETSIGTYPE
_rl_signal_handler(sig)1336b445a62SJohn Marino _rl_signal_handler (sig)
1346b445a62SJohn Marino      int sig;
1356b445a62SJohn Marino {
1366b445a62SJohn Marino   _rl_caught_signal = 0;	/* XXX */
1376b445a62SJohn Marino 
1386b445a62SJohn Marino   _rl_handle_signal (sig);
1396b445a62SJohn Marino   SIGHANDLER_RETURN;
1406b445a62SJohn Marino }
1416b445a62SJohn Marino 
1426b445a62SJohn Marino static RETSIGTYPE
rl_signal_handler(sig)1436b445a62SJohn Marino rl_signal_handler (sig)
1446b445a62SJohn Marino      int sig;
1456b445a62SJohn Marino {
1466b445a62SJohn Marino   if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK))
1476b445a62SJohn Marino     {
1486b445a62SJohn Marino       _rl_interrupt_immediately = 0;
1496b445a62SJohn Marino       _rl_handle_signal (sig);
1506b445a62SJohn Marino     }
1516b445a62SJohn Marino   else
1526b445a62SJohn Marino     _rl_caught_signal = sig;
1536b445a62SJohn Marino 
1546b445a62SJohn Marino   SIGHANDLER_RETURN;
1556b445a62SJohn Marino }
1566b445a62SJohn Marino 
1576b445a62SJohn Marino static RETSIGTYPE
_rl_handle_signal(sig)1586b445a62SJohn Marino _rl_handle_signal (sig)
1596b445a62SJohn Marino      int sig;
1606b445a62SJohn Marino {
1616b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
1626b445a62SJohn Marino   sigset_t set;
1636b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
1646b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
1656b445a62SJohn Marino   long omask;
1666b445a62SJohn Marino #  else /* !HAVE_BSD_SIGNALS */
1676b445a62SJohn Marino   sighandler_cxt dummy_cxt;	/* needed for rl_set_sighandler call */
1686b445a62SJohn Marino #  endif /* !HAVE_BSD_SIGNALS */
1696b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
1706b445a62SJohn Marino 
1716b445a62SJohn Marino   RL_SETSTATE(RL_STATE_SIGHANDLER);
1726b445a62SJohn Marino 
1736b445a62SJohn Marino #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
1746b445a62SJohn Marino   /* Since the signal will not be blocked while we are in the signal
1756b445a62SJohn Marino      handler, ignore it until rl_clear_signals resets the catcher. */
1766b445a62SJohn Marino #  if defined (SIGALRM)
1776b445a62SJohn Marino   if (sig == SIGINT || sig == SIGALRM)
1786b445a62SJohn Marino #  else
1796b445a62SJohn Marino   if (sig == SIGINT)
1806b445a62SJohn Marino #  endif
1816b445a62SJohn Marino     rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
1826b445a62SJohn Marino #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
1836b445a62SJohn Marino 
1846b445a62SJohn Marino   switch (sig)
1856b445a62SJohn Marino     {
1866b445a62SJohn Marino     case SIGINT:
1876b445a62SJohn Marino       _rl_reset_completion_state ();
1886b445a62SJohn Marino       rl_free_line_state ();
1896b445a62SJohn Marino       /* FALLTHROUGH */
1906b445a62SJohn Marino 
1916b445a62SJohn Marino     case SIGTERM:
1926b445a62SJohn Marino #if defined (SIGTSTP)
1936b445a62SJohn Marino     case SIGTSTP:
1946b445a62SJohn Marino     case SIGTTOU:
1956b445a62SJohn Marino     case SIGTTIN:
1966b445a62SJohn Marino #endif /* SIGTSTP */
1976b445a62SJohn Marino #if defined (SIGALRM)
1986b445a62SJohn Marino     case SIGALRM:
1996b445a62SJohn Marino #endif
2006b445a62SJohn Marino #if defined (SIGQUIT)
2016b445a62SJohn Marino     case SIGQUIT:
2026b445a62SJohn Marino #endif
2036b445a62SJohn Marino       rl_echo_signal_char (sig);
2046b445a62SJohn Marino       rl_cleanup_after_signal ();
2056b445a62SJohn Marino 
2066b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
2076b445a62SJohn Marino       sigemptyset (&set);
2086b445a62SJohn Marino       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
2096b445a62SJohn Marino       sigdelset (&set, sig);
2106b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
2116b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
2126b445a62SJohn Marino       omask = sigblock (0);
2136b445a62SJohn Marino #  endif /* HAVE_BSD_SIGNALS */
2146b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
2156b445a62SJohn Marino 
2166b445a62SJohn Marino #if defined (__EMX__)
2176b445a62SJohn Marino       signal (sig, SIG_ACK);
2186b445a62SJohn Marino #endif
2196b445a62SJohn Marino 
2206b445a62SJohn Marino #if defined (HAVE_KILL)
2216b445a62SJohn Marino       kill (getpid (), sig);
2226b445a62SJohn Marino #else
2236b445a62SJohn Marino       raise (sig);		/* assume we have raise */
2246b445a62SJohn Marino #endif
2256b445a62SJohn Marino 
2266b445a62SJohn Marino       /* Let the signal that we just sent through.  */
2276b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
2286b445a62SJohn Marino       sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
2296b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
2306b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
2316b445a62SJohn Marino       sigsetmask (omask & ~(sigmask (sig)));
2326b445a62SJohn Marino #  endif /* HAVE_BSD_SIGNALS */
2336b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
2346b445a62SJohn Marino 
2356b445a62SJohn Marino       rl_reset_after_signal ();
2366b445a62SJohn Marino     }
2376b445a62SJohn Marino 
2386b445a62SJohn Marino   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
2396b445a62SJohn Marino   SIGHANDLER_RETURN;
2406b445a62SJohn Marino }
2416b445a62SJohn Marino 
2426b445a62SJohn Marino #if defined (SIGWINCH)
2436b445a62SJohn Marino static RETSIGTYPE
rl_sigwinch_handler(sig)2446b445a62SJohn Marino rl_sigwinch_handler (sig)
2456b445a62SJohn Marino      int sig;
2466b445a62SJohn Marino {
2476b445a62SJohn Marino   SigHandler *oh;
2486b445a62SJohn Marino 
2496b445a62SJohn Marino #if defined (MUST_REINSTALL_SIGHANDLERS)
2506b445a62SJohn Marino   sighandler_cxt dummy_winch;
2516b445a62SJohn Marino 
2526b445a62SJohn Marino   /* We don't want to change old_winch -- it holds the state of SIGWINCH
2536b445a62SJohn Marino      disposition set by the calling application.  We need this state
2546b445a62SJohn Marino      because we call the application's SIGWINCH handler after updating
2556b445a62SJohn Marino      our own idea of the screen size. */
2566b445a62SJohn Marino   rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
2576b445a62SJohn Marino #endif
2586b445a62SJohn Marino 
2596b445a62SJohn Marino   RL_SETSTATE(RL_STATE_SIGHANDLER);
2606b445a62SJohn Marino   rl_resize_terminal ();
2616b445a62SJohn Marino 
2626b445a62SJohn Marino   /* If another sigwinch handler has been installed, call it. */
2636b445a62SJohn Marino   oh = (SigHandler *)old_winch.sa_handler;
2646b445a62SJohn Marino   if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
2656b445a62SJohn Marino     (*oh) (sig);
2666b445a62SJohn Marino 
2676b445a62SJohn Marino   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
2686b445a62SJohn Marino   SIGHANDLER_RETURN;
2696b445a62SJohn Marino }
2706b445a62SJohn Marino #endif  /* SIGWINCH */
2716b445a62SJohn Marino 
2726b445a62SJohn Marino /* Functions to manage signal handling. */
2736b445a62SJohn Marino 
2746b445a62SJohn Marino #if !defined (HAVE_POSIX_SIGNALS)
2756b445a62SJohn Marino static int
rl_sigaction(sig,nh,oh)2766b445a62SJohn Marino rl_sigaction (sig, nh, oh)
2776b445a62SJohn Marino      int sig;
2786b445a62SJohn Marino      sighandler_cxt *nh, *oh;
2796b445a62SJohn Marino {
2806b445a62SJohn Marino   oh->sa_handler = signal (sig, nh->sa_handler);
2816b445a62SJohn Marino   return 0;
2826b445a62SJohn Marino }
2836b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
2846b445a62SJohn Marino 
2856b445a62SJohn Marino /* Set up a readline-specific signal handler, saving the old signal
2866b445a62SJohn Marino    information in OHANDLER.  Return the old signal handler, like
2876b445a62SJohn Marino    signal(). */
2886b445a62SJohn Marino static SigHandler *
rl_set_sighandler(sig,handler,ohandler)2896b445a62SJohn Marino rl_set_sighandler (sig, handler, ohandler)
2906b445a62SJohn Marino      int sig;
2916b445a62SJohn Marino      SigHandler *handler;
2926b445a62SJohn Marino      sighandler_cxt *ohandler;
2936b445a62SJohn Marino {
2946b445a62SJohn Marino   sighandler_cxt old_handler;
2956b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
2966b445a62SJohn Marino   struct sigaction act;
2976b445a62SJohn Marino 
2986b445a62SJohn Marino   act.sa_handler = handler;
2996b445a62SJohn Marino #  if defined (SIGWINCH)
3006b445a62SJohn Marino   act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
3016b445a62SJohn Marino #  else
3026b445a62SJohn Marino   act.sa_flags = 0;
3036b445a62SJohn Marino #  endif /* SIGWINCH */
3046b445a62SJohn Marino   sigemptyset (&act.sa_mask);
3056b445a62SJohn Marino   sigemptyset (&ohandler->sa_mask);
3066b445a62SJohn Marino   sigaction (sig, &act, &old_handler);
3076b445a62SJohn Marino #else
3086b445a62SJohn Marino   old_handler.sa_handler = (SigHandler *)signal (sig, handler);
3096b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
3106b445a62SJohn Marino 
3116b445a62SJohn Marino   /* XXX -- assume we have memcpy */
3126b445a62SJohn Marino   /* If rl_set_signals is called twice in a row, don't set the old handler to
3136b445a62SJohn Marino      rl_signal_handler, because that would cause infinite recursion. */
3146b445a62SJohn Marino   if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
3156b445a62SJohn Marino     memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
3166b445a62SJohn Marino 
3176b445a62SJohn Marino   return (ohandler->sa_handler);
3186b445a62SJohn Marino }
3196b445a62SJohn Marino 
3206b445a62SJohn Marino static void
rl_maybe_set_sighandler(sig,handler,ohandler)3216b445a62SJohn Marino rl_maybe_set_sighandler (sig, handler, ohandler)
3226b445a62SJohn Marino      int sig;
3236b445a62SJohn Marino      SigHandler *handler;
3246b445a62SJohn Marino      sighandler_cxt *ohandler;
3256b445a62SJohn Marino {
3266b445a62SJohn Marino   sighandler_cxt dummy;
3276b445a62SJohn Marino   SigHandler *oh;
3286b445a62SJohn Marino 
3296b445a62SJohn Marino   sigemptyset (&dummy.sa_mask);
3306b445a62SJohn Marino   oh = rl_set_sighandler (sig, handler, ohandler);
3316b445a62SJohn Marino   if (oh == (SigHandler *)SIG_IGN)
3326b445a62SJohn Marino     rl_sigaction (sig, ohandler, &dummy);
3336b445a62SJohn Marino }
3346b445a62SJohn Marino 
3356b445a62SJohn Marino int
rl_set_signals()3366b445a62SJohn Marino rl_set_signals ()
3376b445a62SJohn Marino {
3386b445a62SJohn Marino   sighandler_cxt dummy;
3396b445a62SJohn Marino   SigHandler *oh;
3406b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
3416b445a62SJohn Marino   static int sigmask_set = 0;
3426b445a62SJohn Marino   static sigset_t bset, oset;
3436b445a62SJohn Marino #endif
3446b445a62SJohn Marino 
3456b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
3466b445a62SJohn Marino   if (rl_catch_signals && sigmask_set == 0)
3476b445a62SJohn Marino     {
3486b445a62SJohn Marino       sigemptyset (&bset);
3496b445a62SJohn Marino 
3506b445a62SJohn Marino       sigaddset (&bset, SIGINT);
3516b445a62SJohn Marino       sigaddset (&bset, SIGTERM);
3526b445a62SJohn Marino #if defined (SIGQUIT)
3536b445a62SJohn Marino       sigaddset (&bset, SIGQUIT);
3546b445a62SJohn Marino #endif
3556b445a62SJohn Marino #if defined (SIGALRM)
3566b445a62SJohn Marino       sigaddset (&bset, SIGALRM);
3576b445a62SJohn Marino #endif
3586b445a62SJohn Marino #if defined (SIGTSTP)
3596b445a62SJohn Marino       sigaddset (&bset, SIGTSTP);
3606b445a62SJohn Marino #endif
3616b445a62SJohn Marino #if defined (SIGTTIN)
3626b445a62SJohn Marino       sigaddset (&bset, SIGTTIN);
3636b445a62SJohn Marino #endif
3646b445a62SJohn Marino #if defined (SIGTTOU)
3656b445a62SJohn Marino       sigaddset (&bset, SIGTTOU);
3666b445a62SJohn Marino #endif
3676b445a62SJohn Marino       sigmask_set = 1;
3686b445a62SJohn Marino     }
3696b445a62SJohn Marino #endif /* HAVE_POSIX_SIGNALS */
3706b445a62SJohn Marino 
3716b445a62SJohn Marino   if (rl_catch_signals && signals_set_flag == 0)
3726b445a62SJohn Marino     {
3736b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
3746b445a62SJohn Marino       sigemptyset (&oset);
3756b445a62SJohn Marino       sigprocmask (SIG_BLOCK, &bset, &oset);
3766b445a62SJohn Marino #endif
3776b445a62SJohn Marino 
3786b445a62SJohn Marino       rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
3796b445a62SJohn Marino       rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
3806b445a62SJohn Marino #if defined (SIGQUIT)
3816b445a62SJohn Marino       rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
3826b445a62SJohn Marino #endif
3836b445a62SJohn Marino 
3846b445a62SJohn Marino #if defined (SIGALRM)
3856b445a62SJohn Marino       oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
3866b445a62SJohn Marino       if (oh == (SigHandler *)SIG_IGN)
3876b445a62SJohn Marino 	rl_sigaction (SIGALRM, &old_alrm, &dummy);
3886b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
3896b445a62SJohn Marino       /* If the application using readline has already installed a signal
3906b445a62SJohn Marino 	 handler with SA_RESTART, SIGALRM will cause reads to be restarted
3916b445a62SJohn Marino 	 automatically, so readline should just get out of the way.  Since
3926b445a62SJohn Marino 	 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
3936b445a62SJohn Marino       if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
3946b445a62SJohn Marino 	rl_sigaction (SIGALRM, &old_alrm, &dummy);
3956b445a62SJohn Marino #endif /* HAVE_POSIX_SIGNALS */
3966b445a62SJohn Marino #endif /* SIGALRM */
3976b445a62SJohn Marino 
3986b445a62SJohn Marino #if defined (SIGTSTP)
3996b445a62SJohn Marino       rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
4006b445a62SJohn Marino #endif /* SIGTSTP */
4016b445a62SJohn Marino 
4026b445a62SJohn Marino #if defined (SIGTTOU)
4036b445a62SJohn Marino       rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
4046b445a62SJohn Marino #endif /* SIGTTOU */
4056b445a62SJohn Marino 
4066b445a62SJohn Marino #if defined (SIGTTIN)
4076b445a62SJohn Marino       rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
4086b445a62SJohn Marino #endif /* SIGTTIN */
4096b445a62SJohn Marino 
4106b445a62SJohn Marino       signals_set_flag = 1;
4116b445a62SJohn Marino 
4126b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
4136b445a62SJohn Marino       sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
4146b445a62SJohn Marino #endif
4156b445a62SJohn Marino     }
4166b445a62SJohn Marino 
4176b445a62SJohn Marino #if defined (SIGWINCH)
4186b445a62SJohn Marino   if (rl_catch_sigwinch && sigwinch_set_flag == 0)
4196b445a62SJohn Marino     {
4206b445a62SJohn Marino       rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
4216b445a62SJohn Marino       sigwinch_set_flag = 1;
4226b445a62SJohn Marino     }
4236b445a62SJohn Marino #endif /* SIGWINCH */
4246b445a62SJohn Marino 
4256b445a62SJohn Marino   return 0;
4266b445a62SJohn Marino }
4276b445a62SJohn Marino 
4286b445a62SJohn Marino int
rl_clear_signals()4296b445a62SJohn Marino rl_clear_signals ()
4306b445a62SJohn Marino {
4316b445a62SJohn Marino   sighandler_cxt dummy;
4326b445a62SJohn Marino 
4336b445a62SJohn Marino   if (rl_catch_signals && signals_set_flag == 1)
4346b445a62SJohn Marino     {
4356b445a62SJohn Marino       sigemptyset (&dummy.sa_mask);
4366b445a62SJohn Marino 
4376b445a62SJohn Marino       rl_sigaction (SIGINT, &old_int, &dummy);
4386b445a62SJohn Marino       rl_sigaction (SIGTERM, &old_term, &dummy);
4396b445a62SJohn Marino #if defined (SIGQUIT)
4406b445a62SJohn Marino       rl_sigaction (SIGQUIT, &old_quit, &dummy);
4416b445a62SJohn Marino #endif
4426b445a62SJohn Marino #if defined (SIGALRM)
4436b445a62SJohn Marino       rl_sigaction (SIGALRM, &old_alrm, &dummy);
4446b445a62SJohn Marino #endif
4456b445a62SJohn Marino 
4466b445a62SJohn Marino #if defined (SIGTSTP)
4476b445a62SJohn Marino       rl_sigaction (SIGTSTP, &old_tstp, &dummy);
4486b445a62SJohn Marino #endif /* SIGTSTP */
4496b445a62SJohn Marino 
4506b445a62SJohn Marino #if defined (SIGTTOU)
4516b445a62SJohn Marino       rl_sigaction (SIGTTOU, &old_ttou, &dummy);
4526b445a62SJohn Marino #endif /* SIGTTOU */
4536b445a62SJohn Marino 
4546b445a62SJohn Marino #if defined (SIGTTIN)
4556b445a62SJohn Marino       rl_sigaction (SIGTTIN, &old_ttin, &dummy);
4566b445a62SJohn Marino #endif /* SIGTTIN */
4576b445a62SJohn Marino 
4586b445a62SJohn Marino       signals_set_flag = 0;
4596b445a62SJohn Marino     }
4606b445a62SJohn Marino 
4616b445a62SJohn Marino #if defined (SIGWINCH)
4626b445a62SJohn Marino   if (rl_catch_sigwinch && sigwinch_set_flag == 1)
4636b445a62SJohn Marino     {
4646b445a62SJohn Marino       sigemptyset (&dummy.sa_mask);
4656b445a62SJohn Marino       rl_sigaction (SIGWINCH, &old_winch, &dummy);
4666b445a62SJohn Marino       sigwinch_set_flag = 0;
4676b445a62SJohn Marino     }
4686b445a62SJohn Marino #endif
4696b445a62SJohn Marino 
4706b445a62SJohn Marino   return 0;
4716b445a62SJohn Marino }
4726b445a62SJohn Marino 
4736b445a62SJohn Marino /* Clean up the terminal and readline state after catching a signal, before
4746b445a62SJohn Marino    resending it to the calling application. */
4756b445a62SJohn Marino void
rl_cleanup_after_signal()4766b445a62SJohn Marino rl_cleanup_after_signal ()
4776b445a62SJohn Marino {
4786b445a62SJohn Marino   _rl_clean_up_for_exit ();
4796b445a62SJohn Marino   if (rl_deprep_term_function)
4806b445a62SJohn Marino     (*rl_deprep_term_function) ();
4816b445a62SJohn Marino   rl_clear_pending_input ();
4826b445a62SJohn Marino   rl_clear_signals ();
4836b445a62SJohn Marino }
4846b445a62SJohn Marino 
4856b445a62SJohn Marino /* Reset the terminal and readline state after a signal handler returns. */
4866b445a62SJohn Marino void
rl_reset_after_signal()4876b445a62SJohn Marino rl_reset_after_signal ()
4886b445a62SJohn Marino {
4896b445a62SJohn Marino   if (rl_prep_term_function)
4906b445a62SJohn Marino     (*rl_prep_term_function) (_rl_meta_flag);
4916b445a62SJohn Marino   rl_set_signals ();
4926b445a62SJohn Marino }
4936b445a62SJohn Marino 
4946b445a62SJohn Marino /* Free up the readline variable line state for the current line (undo list,
4956b445a62SJohn Marino    any partial history entry, any keyboard macros in progress, and any
4966b445a62SJohn Marino    numeric arguments in process) after catching a signal, before calling
4976b445a62SJohn Marino    rl_cleanup_after_signal(). */
4986b445a62SJohn Marino void
rl_free_line_state()4996b445a62SJohn Marino rl_free_line_state ()
5006b445a62SJohn Marino {
5016b445a62SJohn Marino   register HIST_ENTRY *entry;
5026b445a62SJohn Marino 
5036b445a62SJohn Marino   rl_free_undo_list ();
5046b445a62SJohn Marino 
5056b445a62SJohn Marino   entry = current_history ();
5066b445a62SJohn Marino   if (entry)
5076b445a62SJohn Marino     entry->data = (char *)NULL;
5086b445a62SJohn Marino 
5096b445a62SJohn Marino   _rl_kill_kbd_macro ();
5106b445a62SJohn Marino   rl_clear_message ();
5116b445a62SJohn Marino   _rl_reset_argument ();
5126b445a62SJohn Marino }
5136b445a62SJohn Marino 
5146b445a62SJohn Marino #endif  /* HANDLE_SIGNALS */
5156b445a62SJohn Marino 
5166b445a62SJohn Marino /* **************************************************************** */
5176b445a62SJohn Marino /*								    */
5186b445a62SJohn Marino /*			   SIGINT Management			    */
5196b445a62SJohn Marino /*								    */
5206b445a62SJohn Marino /* **************************************************************** */
5216b445a62SJohn Marino 
5226b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
5236b445a62SJohn Marino static sigset_t sigint_set, sigint_oset;
5246b445a62SJohn Marino static sigset_t sigwinch_set, sigwinch_oset;
5256b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
5266b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
5276b445a62SJohn Marino static int sigint_oldmask;
5286b445a62SJohn Marino static int sigwinch_oldmask;
5296b445a62SJohn Marino #  endif /* HAVE_BSD_SIGNALS */
5306b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
5316b445a62SJohn Marino 
5326b445a62SJohn Marino static int sigint_blocked;
5336b445a62SJohn Marino static int sigwinch_blocked;
5346b445a62SJohn Marino 
5356b445a62SJohn Marino /* Cause SIGINT to not be delivered until the corresponding call to
5366b445a62SJohn Marino    release_sigint(). */
5376b445a62SJohn Marino void
_rl_block_sigint()5386b445a62SJohn Marino _rl_block_sigint ()
5396b445a62SJohn Marino {
5406b445a62SJohn Marino   if (sigint_blocked)
5416b445a62SJohn Marino     return;
5426b445a62SJohn Marino 
5436b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
5446b445a62SJohn Marino   sigemptyset (&sigint_set);
5456b445a62SJohn Marino   sigemptyset (&sigint_oset);
5466b445a62SJohn Marino   sigaddset (&sigint_set, SIGINT);
5476b445a62SJohn Marino   sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
5486b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
5496b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
5506b445a62SJohn Marino   sigint_oldmask = sigblock (sigmask (SIGINT));
5516b445a62SJohn Marino #  else /* !HAVE_BSD_SIGNALS */
5526b445a62SJohn Marino #    if defined (HAVE_USG_SIGHOLD)
5536b445a62SJohn Marino   sighold (SIGINT);
5546b445a62SJohn Marino #    endif /* HAVE_USG_SIGHOLD */
5556b445a62SJohn Marino #  endif /* !HAVE_BSD_SIGNALS */
5566b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
5576b445a62SJohn Marino 
5586b445a62SJohn Marino   sigint_blocked = 1;
5596b445a62SJohn Marino }
5606b445a62SJohn Marino 
5616b445a62SJohn Marino /* Allow SIGINT to be delivered. */
5626b445a62SJohn Marino void
_rl_release_sigint()5636b445a62SJohn Marino _rl_release_sigint ()
5646b445a62SJohn Marino {
5656b445a62SJohn Marino   if (sigint_blocked == 0)
5666b445a62SJohn Marino     return;
5676b445a62SJohn Marino 
5686b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
5696b445a62SJohn Marino   sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
5706b445a62SJohn Marino #else
5716b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
5726b445a62SJohn Marino   sigsetmask (sigint_oldmask);
5736b445a62SJohn Marino #  else /* !HAVE_BSD_SIGNALS */
5746b445a62SJohn Marino #    if defined (HAVE_USG_SIGHOLD)
5756b445a62SJohn Marino   sigrelse (SIGINT);
5766b445a62SJohn Marino #    endif /* HAVE_USG_SIGHOLD */
5776b445a62SJohn Marino #  endif /* !HAVE_BSD_SIGNALS */
5786b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
5796b445a62SJohn Marino 
5806b445a62SJohn Marino   sigint_blocked = 0;
5816b445a62SJohn Marino }
5826b445a62SJohn Marino 
583*ef5ccd6cSJohn Marino #ifdef SIGWINCH
5846b445a62SJohn Marino /* Cause SIGWINCH to not be delivered until the corresponding call to
5856b445a62SJohn Marino    release_sigwinch(). */
5866b445a62SJohn Marino void
_rl_block_sigwinch()5876b445a62SJohn Marino _rl_block_sigwinch ()
5886b445a62SJohn Marino {
5896b445a62SJohn Marino   if (sigwinch_blocked)
5906b445a62SJohn Marino     return;
5916b445a62SJohn Marino 
5926b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
5936b445a62SJohn Marino   sigemptyset (&sigwinch_set);
5946b445a62SJohn Marino   sigemptyset (&sigwinch_oset);
5956b445a62SJohn Marino   sigaddset (&sigwinch_set, SIGWINCH);
5966b445a62SJohn Marino   sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
5976b445a62SJohn Marino #else /* !HAVE_POSIX_SIGNALS */
5986b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
5996b445a62SJohn Marino   sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
6006b445a62SJohn Marino #  else /* !HAVE_BSD_SIGNALS */
6016b445a62SJohn Marino #    if defined (HAVE_USG_SIGHOLD)
6026b445a62SJohn Marino   sighold (SIGWINCH);
6036b445a62SJohn Marino #    endif /* HAVE_USG_SIGHOLD */
6046b445a62SJohn Marino #  endif /* !HAVE_BSD_SIGNALS */
6056b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
6066b445a62SJohn Marino 
6076b445a62SJohn Marino   sigwinch_blocked = 1;
6086b445a62SJohn Marino }
6096b445a62SJohn Marino 
6106b445a62SJohn Marino /* Allow SIGWINCH to be delivered. */
6116b445a62SJohn Marino void
_rl_release_sigwinch()6126b445a62SJohn Marino _rl_release_sigwinch ()
6136b445a62SJohn Marino {
6146b445a62SJohn Marino   if (sigwinch_blocked == 0)
6156b445a62SJohn Marino     return;
6166b445a62SJohn Marino 
6176b445a62SJohn Marino #if defined (HAVE_POSIX_SIGNALS)
6186b445a62SJohn Marino   sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
6196b445a62SJohn Marino #else
6206b445a62SJohn Marino #  if defined (HAVE_BSD_SIGNALS)
6216b445a62SJohn Marino   sigsetmask (sigwinch_oldmask);
6226b445a62SJohn Marino #  else /* !HAVE_BSD_SIGNALS */
6236b445a62SJohn Marino #    if defined (HAVE_USG_SIGHOLD)
6246b445a62SJohn Marino   sigrelse (SIGWINCH);
6256b445a62SJohn Marino #    endif /* HAVE_USG_SIGHOLD */
6266b445a62SJohn Marino #  endif /* !HAVE_BSD_SIGNALS */
6276b445a62SJohn Marino #endif /* !HAVE_POSIX_SIGNALS */
6286b445a62SJohn Marino 
6296b445a62SJohn Marino   sigwinch_blocked = 0;
6306b445a62SJohn Marino }
631*ef5ccd6cSJohn Marino #endif /* SIGWINCH */
6326b445a62SJohn Marino 
6336b445a62SJohn Marino /* **************************************************************** */
6346b445a62SJohn Marino /*								    */
6356b445a62SJohn Marino /*		Echoing special control characters		    */
6366b445a62SJohn Marino /*								    */
6376b445a62SJohn Marino /* **************************************************************** */
6386b445a62SJohn Marino void
rl_echo_signal_char(sig)6396b445a62SJohn Marino rl_echo_signal_char (sig)
6406b445a62SJohn Marino      int sig;
6416b445a62SJohn Marino {
6426b445a62SJohn Marino   char cstr[3];
6436b445a62SJohn Marino   int cslen, c;
6446b445a62SJohn Marino 
6456b445a62SJohn Marino   if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
6466b445a62SJohn Marino     return;
6476b445a62SJohn Marino 
6486b445a62SJohn Marino   switch (sig)
6496b445a62SJohn Marino     {
6506b445a62SJohn Marino     case SIGINT:  c = _rl_intr_char; break;
6516b445a62SJohn Marino #if defined (SIGQUIT)
6526b445a62SJohn Marino     case SIGQUIT: c = _rl_quit_char; break;
6536b445a62SJohn Marino #endif
6546b445a62SJohn Marino #if defined (SIGTSTP)
6556b445a62SJohn Marino     case SIGTSTP: c = _rl_susp_char; break;
6566b445a62SJohn Marino #endif
6576b445a62SJohn Marino     default: return;
6586b445a62SJohn Marino     }
6596b445a62SJohn Marino 
6606b445a62SJohn Marino   if (CTRL_CHAR (c) || c == RUBOUT)
6616b445a62SJohn Marino     {
6626b445a62SJohn Marino       cstr[0] = '^';
6636b445a62SJohn Marino       cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
6646b445a62SJohn Marino       cstr[cslen = 2] = '\0';
6656b445a62SJohn Marino     }
6666b445a62SJohn Marino   else
6676b445a62SJohn Marino     {
6686b445a62SJohn Marino       cstr[0] = c;
6696b445a62SJohn Marino       cstr[cslen = 1] = '\0';
6706b445a62SJohn Marino     }
6716b445a62SJohn Marino 
6726b445a62SJohn Marino   _rl_output_some_chars (cstr, cslen);
6736b445a62SJohn Marino }
674