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