121308Sache/* signals.c -- signal handling support for readline. */
221308Sache
3157184Sache/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
421308Sache
521308Sache   This file is part of the GNU Readline Library, a library for
621308Sache   reading lines of text with interactive input and history editing.
721308Sache
821308Sache   The GNU Readline Library is free software; you can redistribute it
921308Sache   and/or modify it under the terms of the GNU General Public License
1058310Sache   as published by the Free Software Foundation; either version 2, or
1121308Sache   (at your option) any later version.
1221308Sache
1321308Sache   The GNU Readline Library is distributed in the hope that it will be
1421308Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1521308Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1621308Sache   GNU General Public License for more details.
1721308Sache
1821308Sache   The GNU General Public License is often shipped with GNU software, and
1921308Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
2021308Sache   have a copy of the license, write to the Free Software Foundation,
2158310Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
2221308Sache#define READLINE_LIBRARY
2321308Sache
2421308Sache#if defined (HAVE_CONFIG_H)
2521308Sache#  include <config.h>
2621308Sache#endif
2721308Sache
2821308Sache#include <stdio.h>		/* Just for NULL.  Yuck. */
2921308Sache#include <sys/types.h>
3021308Sache#include <signal.h>
3121308Sache
3221308Sache#if defined (HAVE_UNISTD_H)
3321308Sache#  include <unistd.h>
3421308Sache#endif /* HAVE_UNISTD_H */
3521308Sache
3621308Sache/* System-specific feature definitions and include files. */
3721308Sache#include "rldefs.h"
3821308Sache
3921308Sache#if defined (GWINSZ_IN_SYS_IOCTL)
4021308Sache#  include <sys/ioctl.h>
4121308Sache#endif /* GWINSZ_IN_SYS_IOCTL */
4221308Sache
4321308Sache#if defined (HANDLE_SIGNALS)
4421308Sache/* Some standard library routines. */
4521308Sache#include "readline.h"
4621308Sache#include "history.h"
4721308Sache
4858310Sache#include "rlprivate.h"
4958310Sache
5021308Sache#if !defined (RETSIGTYPE)
5121308Sache#  if defined (VOID_SIGHANDLER)
5221308Sache#    define RETSIGTYPE void
5321308Sache#  else
5421308Sache#    define RETSIGTYPE int
5521308Sache#  endif /* !VOID_SIGHANDLER */
5621308Sache#endif /* !RETSIGTYPE */
5721308Sache
5821308Sache#if defined (VOID_SIGHANDLER)
5921308Sache#  define SIGHANDLER_RETURN return
6021308Sache#else
6121308Sache#  define SIGHANDLER_RETURN return (0)
6221308Sache#endif
6321308Sache
6475406Sache/* This typedef is equivalent to the one for Function; it allows us
6521308Sache   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
6621308Sachetypedef RETSIGTYPE SigHandler ();
6721308Sache
6858310Sache#if defined (HAVE_POSIX_SIGNALS)
6958310Sachetypedef struct sigaction sighandler_cxt;
7058310Sache#  define rl_sigaction(s, nh, oh)	sigaction(s, nh, oh)
7158310Sache#else
7258310Sachetypedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
7358310Sache#  define sigemptyset(m)
7458310Sache#endif /* !HAVE_POSIX_SIGNALS */
7547558Sache
76136644Sache#ifndef SA_RESTART
77136644Sache#  define SA_RESTART 0
78136644Sache#endif
79136644Sache
80119610Sachestatic SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
81119610Sachestatic void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
8247558Sache
8347558Sache/* Exported variables for use by applications. */
8447558Sache
8547558Sache/* If non-zero, readline will install its own signal handlers for
8647558Sache   SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
8747558Sacheint rl_catch_signals = 1;
8847558Sache
8947558Sache/* If non-zero, readline will install a signal handler for SIGWINCH. */
9047558Sache#ifdef SIGWINCH
9147558Sacheint rl_catch_sigwinch = 1;
92136644Sache#else
93136644Sacheint rl_catch_sigwinch = 0;	/* for the readline state struct in readline.c */
9447558Sache#endif
9547558Sache
9647558Sachestatic int signals_set_flag;
9747558Sachestatic int sigwinch_set_flag;
9847558Sache
9921308Sache/* **************************************************************** */
10021308Sache/*					        		    */
10121308Sache/*			   Signal Handling                          */
10221308Sache/*								    */
10321308Sache/* **************************************************************** */
10421308Sache
10547558Sachestatic sighandler_cxt old_int, old_term, old_alrm, old_quit;
10647558Sache#if defined (SIGTSTP)
10726497Sachestatic sighandler_cxt old_tstp, old_ttou, old_ttin;
10826497Sache#endif
10921308Sache#if defined (SIGWINCH)
11021308Sachestatic sighandler_cxt old_winch;
11121308Sache#endif
11221308Sache
11321308Sache/* Readline signal handler functions. */
11421308Sache
11521308Sachestatic RETSIGTYPE
11621308Sacherl_signal_handler (sig)
11721308Sache     int sig;
11821308Sache{
11921308Sache#if defined (HAVE_POSIX_SIGNALS)
12021308Sache  sigset_t set;
12121308Sache#else /* !HAVE_POSIX_SIGNALS */
12221308Sache#  if defined (HAVE_BSD_SIGNALS)
12321308Sache  long omask;
12426497Sache#  else /* !HAVE_BSD_SIGNALS */
12526497Sache  sighandler_cxt dummy_cxt;	/* needed for rl_set_sighandler call */
12626497Sache#  endif /* !HAVE_BSD_SIGNALS */
12721308Sache#endif /* !HAVE_POSIX_SIGNALS */
12821308Sache
12975406Sache  RL_SETSTATE(RL_STATE_SIGHANDLER);
13075406Sache
13121308Sache#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
13221308Sache  /* Since the signal will not be blocked while we are in the signal
13321308Sache     handler, ignore it until rl_clear_signals resets the catcher. */
134157184Sache#  if defined (SIGALRM)
13521308Sache  if (sig == SIGINT || sig == SIGALRM)
136157184Sache#  else
137157184Sache  if (sig == SIGINT)
138157184Sache#  endif
13926497Sache    rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
14021308Sache#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
14121308Sache
14221308Sache  switch (sig)
14321308Sache    {
14421308Sache    case SIGINT:
14547558Sache      rl_free_line_state ();
14647558Sache      /* FALLTHROUGH */
14721308Sache
148157184Sache    case SIGTERM:
14921308Sache#if defined (SIGTSTP)
15021308Sache    case SIGTSTP:
15121308Sache    case SIGTTOU:
15221308Sache    case SIGTTIN:
15321308Sache#endif /* SIGTSTP */
154157184Sache#if defined (SIGALRM)
15521308Sache    case SIGALRM:
156157184Sache#endif
157157184Sache#if defined (SIGQUIT)
15847558Sache    case SIGQUIT:
159157184Sache#endif
16047558Sache      rl_cleanup_after_signal ();
16121308Sache
16221308Sache#if defined (HAVE_POSIX_SIGNALS)
163165670Sache      sigemptyset (&set);
16421308Sache      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
16521308Sache      sigdelset (&set, sig);
16621308Sache#else /* !HAVE_POSIX_SIGNALS */
16721308Sache#  if defined (HAVE_BSD_SIGNALS)
16821308Sache      omask = sigblock (0);
16921308Sache#  endif /* HAVE_BSD_SIGNALS */
17021308Sache#endif /* !HAVE_POSIX_SIGNALS */
17121308Sache
17258310Sache#if defined (__EMX__)
17358310Sache      signal (sig, SIG_ACK);
17458310Sache#endif
17558310Sache
176157184Sache#if defined (HAVE_KILL)
17721308Sache      kill (getpid (), sig);
178157184Sache#else
179157184Sache      raise (sig);		/* assume we have raise */
180157184Sache#endif
18121308Sache
18221308Sache      /* Let the signal that we just sent through.  */
18321308Sache#if defined (HAVE_POSIX_SIGNALS)
18421308Sache      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
18521308Sache#else /* !HAVE_POSIX_SIGNALS */
18621308Sache#  if defined (HAVE_BSD_SIGNALS)
18721308Sache      sigsetmask (omask & ~(sigmask (sig)));
18821308Sache#  endif /* HAVE_BSD_SIGNALS */
18921308Sache#endif /* !HAVE_POSIX_SIGNALS */
19021308Sache
19147558Sache      rl_reset_after_signal ();
19221308Sache    }
19321308Sache
19475406Sache  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
19521308Sache  SIGHANDLER_RETURN;
19621308Sache}
19721308Sache
19821308Sache#if defined (SIGWINCH)
19921308Sachestatic RETSIGTYPE
20047558Sacherl_sigwinch_handler (sig)
20121308Sache     int sig;
20221308Sache{
20321308Sache  SigHandler *oh;
20421308Sache
20526497Sache#if defined (MUST_REINSTALL_SIGHANDLERS)
20626497Sache  sighandler_cxt dummy_winch;
20726497Sache
20826497Sache  /* We don't want to change old_winch -- it holds the state of SIGWINCH
20926497Sache     disposition set by the calling application.  We need this state
21026497Sache     because we call the application's SIGWINCH handler after updating
21126497Sache     our own idea of the screen size. */
21247558Sache  rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
21326497Sache#endif
21426497Sache
21575406Sache  RL_SETSTATE(RL_STATE_SIGHANDLER);
21647558Sache  rl_resize_terminal ();
21721308Sache
21821308Sache  /* If another sigwinch handler has been installed, call it. */
21921308Sache  oh = (SigHandler *)old_winch.sa_handler;
22021308Sache  if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
22121308Sache    (*oh) (sig);
22221308Sache
22375406Sache  RL_UNSETSTATE(RL_STATE_SIGHANDLER);
22421308Sache  SIGHANDLER_RETURN;
22521308Sache}
22621308Sache#endif  /* SIGWINCH */
22721308Sache
22821308Sache/* Functions to manage signal handling. */
22921308Sache
23021308Sache#if !defined (HAVE_POSIX_SIGNALS)
23121308Sachestatic int
23221308Sacherl_sigaction (sig, nh, oh)
23321308Sache     int sig;
23421308Sache     sighandler_cxt *nh, *oh;
23521308Sache{
23621308Sache  oh->sa_handler = signal (sig, nh->sa_handler);
23721308Sache  return 0;
23821308Sache}
23921308Sache#endif /* !HAVE_POSIX_SIGNALS */
24021308Sache
24121308Sache/* Set up a readline-specific signal handler, saving the old signal
24221308Sache   information in OHANDLER.  Return the old signal handler, like
24321308Sache   signal(). */
24421308Sachestatic SigHandler *
24521308Sacherl_set_sighandler (sig, handler, ohandler)
24621308Sache     int sig;
24721308Sache     SigHandler *handler;
24821308Sache     sighandler_cxt *ohandler;
24921308Sache{
25058310Sache  sighandler_cxt old_handler;
25121308Sache#if defined (HAVE_POSIX_SIGNALS)
25221308Sache  struct sigaction act;
25321308Sache
25421308Sache  act.sa_handler = handler;
255136644Sache  act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
25621308Sache  sigemptyset (&act.sa_mask);
25721308Sache  sigemptyset (&ohandler->sa_mask);
25858310Sache  sigaction (sig, &act, &old_handler);
25921308Sache#else
26058310Sache  old_handler.sa_handler = (SigHandler *)signal (sig, handler);
26121308Sache#endif /* !HAVE_POSIX_SIGNALS */
26258310Sache
26358310Sache  /* XXX -- assume we have memcpy */
26458310Sache  /* If rl_set_signals is called twice in a row, don't set the old handler to
26558310Sache     rl_signal_handler, because that would cause infinite recursion. */
26658310Sache  if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
26758310Sache    memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
26858310Sache
26921308Sache  return (ohandler->sa_handler);
27021308Sache}
27121308Sache
27247558Sachestatic void
27347558Sacherl_maybe_set_sighandler (sig, handler, ohandler)
27447558Sache     int sig;
27547558Sache     SigHandler *handler;
27647558Sache     sighandler_cxt *ohandler;
27747558Sache{
27847558Sache  sighandler_cxt dummy;
27947558Sache  SigHandler *oh;
28047558Sache
28147558Sache  sigemptyset (&dummy.sa_mask);
28247558Sache  oh = rl_set_sighandler (sig, handler, ohandler);
28347558Sache  if (oh == (SigHandler *)SIG_IGN)
28447558Sache    rl_sigaction (sig, ohandler, &dummy);
28547558Sache}
28647558Sache
28721308Sacheint
28821308Sacherl_set_signals ()
28921308Sache{
29021308Sache  sighandler_cxt dummy;
29121308Sache  SigHandler *oh;
292165670Sache#if defined (HAVE_POSIX_SIGNALS)
293165670Sache  static int sigmask_set = 0;
294165670Sache  static sigset_t bset, oset;
295165670Sache#endif
29621308Sache
297165670Sache#if defined (HAVE_POSIX_SIGNALS)
298165670Sache  if (rl_catch_signals && sigmask_set == 0)
299165670Sache    {
300165670Sache      sigemptyset (&bset);
301165670Sache
302165670Sache      sigaddset (&bset, SIGINT);
303165670Sache      sigaddset (&bset, SIGINT);
304165670Sache#if defined (SIGQUIT)
305165670Sache      sigaddset (&bset, SIGQUIT);
306165670Sache#endif
307165670Sache#if defined (SIGALRM)
308165670Sache      sigaddset (&bset, SIGALRM);
309165670Sache#endif
310165670Sache#if defined (SIGTSTP)
311165670Sache      sigaddset (&bset, SIGTSTP);
312165670Sache#endif
313165670Sache#if defined (SIGTTIN)
314165670Sache      sigaddset (&bset, SIGTTIN);
315165670Sache#endif
316165670Sache#if defined (SIGTTOU)
317165670Sache      sigaddset (&bset, SIGTTOU);
318165670Sache#endif
319165670Sache      sigmask_set = 1;
320165670Sache    }
321165670Sache#endif /* HAVE_POSIX_SIGNALS */
322165670Sache
32347558Sache  if (rl_catch_signals && signals_set_flag == 0)
32447558Sache    {
325165670Sache#if defined (HAVE_POSIX_SIGNALS)
326165670Sache      sigemptyset (&oset);
327165670Sache      sigprocmask (SIG_BLOCK, &bset, &oset);
328165670Sache#endif
329165670Sache
33047558Sache      rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
33147558Sache      rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
332157184Sache#if defined (SIGQUIT)
33347558Sache      rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
334157184Sache#endif
33521308Sache
336157184Sache#if defined (SIGALRM)
33747558Sache      oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
33847558Sache      if (oh == (SigHandler *)SIG_IGN)
33947558Sache	rl_sigaction (SIGALRM, &old_alrm, &dummy);
34021308Sache#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
34147558Sache      /* If the application using readline has already installed a signal
34247558Sache	 handler with SA_RESTART, SIGALRM will cause reads to be restarted
34347558Sache	 automatically, so readline should just get out of the way.  Since
34447558Sache	 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
34547558Sache      if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
34647558Sache	rl_sigaction (SIGALRM, &old_alrm, &dummy);
34721308Sache#endif /* HAVE_POSIX_SIGNALS */
348157184Sache#endif /* SIGALRM */
34921308Sache
35021308Sache#if defined (SIGTSTP)
35147558Sache      rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
35221308Sache#endif /* SIGTSTP */
35321308Sache
35421308Sache#if defined (SIGTTOU)
35547558Sache      rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
35621308Sache#endif /* SIGTTOU */
35721308Sache
35847558Sache#if defined (SIGTTIN)
35947558Sache      rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
36047558Sache#endif /* SIGTTIN */
36126497Sache
36247558Sache      signals_set_flag = 1;
363165670Sache
364165670Sache#if defined (HAVE_POSIX_SIGNALS)
365165670Sache      sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
366165670Sache#endif
36747558Sache    }
36821308Sache
36921308Sache#if defined (SIGWINCH)
37047558Sache  if (rl_catch_sigwinch && sigwinch_set_flag == 0)
37147558Sache    {
37247558Sache      rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
37347558Sache      sigwinch_set_flag = 1;
37447558Sache    }
37521308Sache#endif /* SIGWINCH */
37621308Sache
37721308Sache  return 0;
37821308Sache}
37921308Sache
38021308Sacheint
38121308Sacherl_clear_signals ()
38221308Sache{
38321308Sache  sighandler_cxt dummy;
38421308Sache
38547558Sache  if (rl_catch_signals && signals_set_flag == 1)
38647558Sache    {
38747558Sache      sigemptyset (&dummy.sa_mask);
38821308Sache
38947558Sache      rl_sigaction (SIGINT, &old_int, &dummy);
39047558Sache      rl_sigaction (SIGTERM, &old_term, &dummy);
391157184Sache#if defined (SIGQUIT)
39247558Sache      rl_sigaction (SIGQUIT, &old_quit, &dummy);
393157184Sache#endif
394157184Sache#if defined (SIGALRM)
39547558Sache      rl_sigaction (SIGALRM, &old_alrm, &dummy);
396157184Sache#endif
39721308Sache
39821308Sache#if defined (SIGTSTP)
39947558Sache      rl_sigaction (SIGTSTP, &old_tstp, &dummy);
40047558Sache#endif /* SIGTSTP */
40121308Sache
40221308Sache#if defined (SIGTTOU)
40347558Sache      rl_sigaction (SIGTTOU, &old_ttou, &dummy);
40421308Sache#endif /* SIGTTOU */
40521308Sache
40647558Sache#if defined (SIGTTIN)
40747558Sache      rl_sigaction (SIGTTIN, &old_ttin, &dummy);
40847558Sache#endif /* SIGTTIN */
40926497Sache
41047558Sache      signals_set_flag = 0;
41147558Sache    }
41221308Sache
41321308Sache#if defined (SIGWINCH)
41447558Sache  if (rl_catch_sigwinch && sigwinch_set_flag == 1)
41547558Sache    {
41647558Sache      sigemptyset (&dummy.sa_mask);
41747558Sache      rl_sigaction (SIGWINCH, &old_winch, &dummy);
41847558Sache      sigwinch_set_flag = 0;
41947558Sache    }
42021308Sache#endif
42121308Sache
42221308Sache  return 0;
42321308Sache}
42447558Sache
42547558Sache/* Clean up the terminal and readline state after catching a signal, before
42647558Sache   resending it to the calling application. */
42747558Sachevoid
42847558Sacherl_cleanup_after_signal ()
42947558Sache{
43047558Sache  _rl_clean_up_for_exit ();
431157184Sache  if (rl_deprep_term_function)
432157184Sache    (*rl_deprep_term_function) ();
433165670Sache  rl_clear_pending_input ();
43447558Sache  rl_clear_signals ();
43547558Sache}
43647558Sache
43747558Sache/* Reset the terminal and readline state after a signal handler returns. */
43847558Sachevoid
43947558Sacherl_reset_after_signal ()
44047558Sache{
441157184Sache  if (rl_prep_term_function)
442157184Sache    (*rl_prep_term_function) (_rl_meta_flag);
44347558Sache  rl_set_signals ();
44447558Sache}
44547558Sache
44647558Sache/* Free up the readline variable line state for the current line (undo list,
44747558Sache   any partial history entry, any keyboard macros in progress, and any
44847558Sache   numeric arguments in process) after catching a signal, before calling
44947558Sache   rl_cleanup_after_signal(). */
45047558Sachevoid
45147558Sacherl_free_line_state ()
45247558Sache{
45347558Sache  register HIST_ENTRY *entry;
45447558Sache
45575406Sache  rl_free_undo_list ();
45647558Sache
45747558Sache  entry = current_history ();
45847558Sache  if (entry)
45947558Sache    entry->data = (char *)NULL;
46047558Sache
46147558Sache  _rl_kill_kbd_macro ();
46247558Sache  rl_clear_message ();
463157184Sache  _rl_reset_argument ();
46447558Sache}
46547558Sache
46621308Sache#endif  /* HANDLE_SIGNALS */
467