File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / signals.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 01:01:01 2021 UTC (3 years, 3 months ago) by misho
Branches: readline, MAIN
CVS tags: v8_2p0, v8_1p0, HEAD
readline 8.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>