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