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