File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / signals.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 10 months ago) by misho
Branches: readline, MAIN
CVS tags: v6_3p10_cross, v6_3p10, v6_3, p6, HEAD
readline 6.3

    1: /* signals.c -- signal handling support for readline. */
    2: 
    3: /* Copyright (C) 1987-2011 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 _rl_interrupt_immediately = 0;
  103: int volatile _rl_caught_signal = 0;	/* should be sig_atomic_t, but that requires including <signal.h> everywhere */
  104: 
  105: /* If non-zero, print characters corresponding to received signals as long as
  106:    the user has indicated his desire to do so (_rl_echo_control_chars). */
  107: int _rl_echoctl = 0;
  108: 
  109: int _rl_intr_char = 0;
  110: int _rl_quit_char = 0;
  111: int _rl_susp_char = 0;
  112: 
  113: static int signals_set_flag;
  114: static int sigwinch_set_flag;
  115: 
  116: /* **************************************************************** */
  117: /*					        		    */
  118: /*			   Signal Handling                          */
  119: /*								    */
  120: /* **************************************************************** */
  121: 
  122: static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit;
  123: #if defined (SIGTSTP)
  124: static sighandler_cxt old_tstp, old_ttou, old_ttin;
  125: #endif
  126: #if defined (SIGWINCH)
  127: static sighandler_cxt old_winch;
  128: #endif
  129: 
  130: _rl_sigcleanup_func_t *_rl_sigcleanup;
  131: void *_rl_sigcleanarg;
  132: 
  133: /* Readline signal handler functions. */
  134: 
  135: /* Called from RL_CHECK_SIGNALS() macro */
  136: RETSIGTYPE
  137: _rl_signal_handler (sig)
  138:      int sig;
  139: {
  140:   _rl_caught_signal = 0;	/* XXX */
  141: 
  142: #if defined (SIGWINCH)
  143:   if (sig == SIGWINCH)
  144:     {
  145:       rl_resize_terminal ();
  146:       /* XXX - experimental for now */
  147:       /* Call a signal hook because though we called the original signal handler
  148: 	 in rl_sigwinch_handler below, we will not resend the signal to
  149: 	 ourselves. */
  150:       if (rl_signal_event_hook)
  151: 	(*rl_signal_event_hook) ();
  152:     }
  153:   else
  154: #endif
  155:     _rl_handle_signal (sig);
  156: 
  157:   SIGHANDLER_RETURN;
  158: }
  159: 
  160: static RETSIGTYPE
  161: rl_signal_handler (sig)
  162:      int sig;
  163: {
  164:   if (_rl_interrupt_immediately)
  165:     {
  166:       _rl_interrupt_immediately = 0;
  167:       _rl_handle_signal (sig);
  168:     }
  169:   else
  170:     _rl_caught_signal = sig;
  171: 
  172:   SIGHANDLER_RETURN;
  173: }
  174: 
  175: static RETSIGTYPE
  176: _rl_handle_signal (sig)
  177:      int sig;
  178: {
  179: #if defined (HAVE_POSIX_SIGNALS)
  180:   sigset_t set;
  181: #else /* !HAVE_POSIX_SIGNALS */
  182: #  if defined (HAVE_BSD_SIGNALS)
  183:   long omask;
  184: #  else /* !HAVE_BSD_SIGNALS */
  185:   sighandler_cxt dummy_cxt;	/* needed for rl_set_sighandler call */
  186: #  endif /* !HAVE_BSD_SIGNALS */
  187: #endif /* !HAVE_POSIX_SIGNALS */
  188: 
  189:   RL_SETSTATE(RL_STATE_SIGHANDLER);
  190: 
  191: #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
  192:   /* Since the signal will not be blocked while we are in the signal
  193:      handler, ignore it until rl_clear_signals resets the catcher. */
  194: #  if defined (SIGALRM)
  195:   if (sig == SIGINT || sig == SIGALRM)
  196: #  else
  197:   if (sig == SIGINT)
  198: #  endif
  199:     rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
  200: #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
  201: 
  202:   /* If there's a sig cleanup function registered, call it and `deregister'
  203:      the cleanup function to avoid multiple calls */
  204:   if (_rl_sigcleanup)
  205:     {
  206:       (*_rl_sigcleanup) (sig, _rl_sigcleanarg);
  207:       _rl_sigcleanup = 0;
  208:       _rl_sigcleanarg = 0;
  209:     }
  210:     
  211:   switch (sig)
  212:     {
  213:     case SIGINT:
  214:       _rl_reset_completion_state ();
  215:       rl_free_line_state ();
  216:       /* FALLTHROUGH */
  217: 
  218:     case SIGTERM:
  219:     case SIGHUP:
  220: #if defined (SIGTSTP)
  221:     case SIGTSTP:
  222:     case SIGTTOU:
  223:     case SIGTTIN:
  224: #endif /* SIGTSTP */
  225: #if defined (SIGALRM)
  226:     case SIGALRM:
  227: #endif
  228: #if defined (SIGQUIT)
  229:     case SIGQUIT:
  230: #endif
  231:       rl_echo_signal_char (sig);
  232:       rl_cleanup_after_signal ();
  233: 
  234: #if defined (HAVE_POSIX_SIGNALS)
  235:       sigemptyset (&set);
  236:       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
  237:       sigdelset (&set, sig);
  238: #else /* !HAVE_POSIX_SIGNALS */
  239: #  if defined (HAVE_BSD_SIGNALS)
  240:       omask = sigblock (0);
  241: #  endif /* HAVE_BSD_SIGNALS */
  242: #endif /* !HAVE_POSIX_SIGNALS */
  243: 
  244: #if defined (__EMX__)
  245:       signal (sig, SIG_ACK);
  246: #endif
  247: 
  248: #if defined (HAVE_KILL)
  249:       kill (getpid (), sig);
  250: #else
  251:       raise (sig);		/* assume we have raise */
  252: #endif
  253: 
  254:       /* Let the signal that we just sent through.  */
  255: #if defined (HAVE_POSIX_SIGNALS)
  256:       sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
  257: #else /* !HAVE_POSIX_SIGNALS */
  258: #  if defined (HAVE_BSD_SIGNALS)
  259:       sigsetmask (omask & ~(sigmask (sig)));
  260: #  endif /* HAVE_BSD_SIGNALS */
  261: #endif /* !HAVE_POSIX_SIGNALS */
  262: 
  263:       rl_reset_after_signal ();      
  264:     }
  265: 
  266:   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
  267:   SIGHANDLER_RETURN;
  268: }
  269: 
  270: #if defined (SIGWINCH)
  271: static RETSIGTYPE
  272: rl_sigwinch_handler (sig)
  273:      int sig;
  274: {
  275:   SigHandler *oh;
  276: 
  277: #if defined (MUST_REINSTALL_SIGHANDLERS)
  278:   sighandler_cxt dummy_winch;
  279: 
  280:   /* We don't want to change old_winch -- it holds the state of SIGWINCH
  281:      disposition set by the calling application.  We need this state
  282:      because we call the application's SIGWINCH handler after updating
  283:      our own idea of the screen size. */
  284:   rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
  285: #endif
  286: 
  287:   RL_SETSTATE(RL_STATE_SIGHANDLER);
  288:   _rl_caught_signal = sig;
  289: 
  290:   /* If another sigwinch handler has been installed, call it. */
  291:   oh = (SigHandler *)old_winch.sa_handler;
  292:   if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
  293:     (*oh) (sig);
  294: 
  295:   RL_UNSETSTATE(RL_STATE_SIGHANDLER);
  296:   SIGHANDLER_RETURN;
  297: }
  298: #endif  /* SIGWINCH */
  299: 
  300: /* Functions to manage signal handling. */
  301: 
  302: #if !defined (HAVE_POSIX_SIGNALS)
  303: static int
  304: rl_sigaction (sig, nh, oh)
  305:      int sig;
  306:      sighandler_cxt *nh, *oh;
  307: {
  308:   oh->sa_handler = signal (sig, nh->sa_handler);
  309:   return 0;
  310: }
  311: #endif /* !HAVE_POSIX_SIGNALS */
  312: 
  313: /* Set up a readline-specific signal handler, saving the old signal
  314:    information in OHANDLER.  Return the old signal handler, like
  315:    signal(). */
  316: static SigHandler *
  317: rl_set_sighandler (sig, handler, ohandler)
  318:      int sig;
  319:      SigHandler *handler;
  320:      sighandler_cxt *ohandler;
  321: {
  322:   sighandler_cxt old_handler;
  323: #if defined (HAVE_POSIX_SIGNALS)
  324:   struct sigaction act;
  325: 
  326:   act.sa_handler = handler;
  327: #  if defined (SIGWINCH)
  328:   act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
  329: #  else
  330:   act.sa_flags = 0;
  331: #  endif /* SIGWINCH */
  332:   sigemptyset (&act.sa_mask);
  333:   sigemptyset (&ohandler->sa_mask);
  334:   sigaction (sig, &act, &old_handler);
  335: #else
  336:   old_handler.sa_handler = (SigHandler *)signal (sig, handler);
  337: #endif /* !HAVE_POSIX_SIGNALS */
  338: 
  339:   /* XXX -- assume we have memcpy */
  340:   /* If rl_set_signals is called twice in a row, don't set the old handler to
  341:      rl_signal_handler, because that would cause infinite recursion. */
  342:   if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
  343:     memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
  344: 
  345:   return (ohandler->sa_handler);
  346: }
  347: 
  348: /* Set disposition of SIG to HANDLER, returning old state in OHANDLER.  Don't
  349:    change disposition if OHANDLER indicates the signal was ignored. */
  350: static void
  351: rl_maybe_set_sighandler (sig, handler, ohandler)
  352:      int sig;
  353:      SigHandler *handler;
  354:      sighandler_cxt *ohandler;
  355: {
  356:   sighandler_cxt dummy;
  357:   SigHandler *oh;
  358: 
  359:   sigemptyset (&dummy.sa_mask);
  360:   dummy.sa_flags = 0;
  361:   oh = rl_set_sighandler (sig, handler, ohandler);
  362:   if (oh == (SigHandler *)SIG_IGN)
  363:     rl_sigaction (sig, ohandler, &dummy);
  364: }
  365: 
  366: /* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
  367:    signal was not being ignored.  MUST only be called for signals whose
  368:    disposition was changed using rl_maybe_set_sighandler or for which the
  369:    SIG_IGN check was performed inline (e.g., SIGALRM below). */
  370: static void
  371: rl_maybe_restore_sighandler (sig, handler)
  372:      int sig;
  373:      sighandler_cxt *handler;
  374: {
  375:   sighandler_cxt dummy;
  376: 
  377:   sigemptyset (&dummy.sa_mask);
  378:   dummy.sa_flags = 0;
  379:   if (handler->sa_handler != SIG_IGN)
  380:     rl_sigaction (sig, handler, &dummy);
  381: }
  382: 
  383: int
  384: rl_set_signals ()
  385: {
  386:   sighandler_cxt dummy;
  387:   SigHandler *oh;
  388: #if defined (HAVE_POSIX_SIGNALS)
  389:   static int sigmask_set = 0;
  390:   static sigset_t bset, oset;
  391: #endif
  392: 
  393: #if defined (HAVE_POSIX_SIGNALS)
  394:   if (rl_catch_signals && sigmask_set == 0)
  395:     {
  396:       sigemptyset (&bset);
  397: 
  398:       sigaddset (&bset, SIGINT);
  399:       sigaddset (&bset, SIGTERM);
  400:       sigaddset (&bset, SIGHUP);
  401: #if defined (SIGQUIT)
  402:       sigaddset (&bset, SIGQUIT);
  403: #endif
  404: #if defined (SIGALRM)
  405:       sigaddset (&bset, SIGALRM);
  406: #endif
  407: #if defined (SIGTSTP)
  408:       sigaddset (&bset, SIGTSTP);
  409: #endif
  410: #if defined (SIGTTIN)
  411:       sigaddset (&bset, SIGTTIN);
  412: #endif
  413: #if defined (SIGTTOU)
  414:       sigaddset (&bset, SIGTTOU);
  415: #endif
  416:       sigmask_set = 1;
  417:     }      
  418: #endif /* HAVE_POSIX_SIGNALS */
  419: 
  420:   if (rl_catch_signals && signals_set_flag == 0)
  421:     {
  422: #if defined (HAVE_POSIX_SIGNALS)
  423:       sigemptyset (&oset);
  424:       sigprocmask (SIG_BLOCK, &bset, &oset);
  425: #endif
  426: 
  427:       rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
  428:       rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
  429:       rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
  430: #if defined (SIGQUIT)
  431:       rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
  432: #endif
  433: 
  434: #if defined (SIGALRM)
  435:       oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
  436:       if (oh == (SigHandler *)SIG_IGN)
  437: 	rl_sigaction (SIGALRM, &old_alrm, &dummy);
  438: #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
  439:       /* If the application using readline has already installed a signal
  440: 	 handler with SA_RESTART, SIGALRM will cause reads to be restarted
  441: 	 automatically, so readline should just get out of the way.  Since
  442: 	 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
  443:       if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
  444: 	rl_sigaction (SIGALRM, &old_alrm, &dummy);
  445: #endif /* HAVE_POSIX_SIGNALS */
  446: #endif /* SIGALRM */
  447: 
  448: #if defined (SIGTSTP)
  449:       rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
  450: #endif /* SIGTSTP */
  451: 
  452: #if defined (SIGTTOU)
  453:       rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
  454: #endif /* SIGTTOU */
  455: 
  456: #if defined (SIGTTIN)
  457:       rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
  458: #endif /* SIGTTIN */
  459: 
  460:       signals_set_flag = 1;
  461: 
  462: #if defined (HAVE_POSIX_SIGNALS)
  463:       sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  464: #endif
  465:     }
  466: 
  467: #if defined (SIGWINCH)
  468:   if (rl_catch_sigwinch && sigwinch_set_flag == 0)
  469:     {
  470:       rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
  471:       sigwinch_set_flag = 1;
  472:     }
  473: #endif /* SIGWINCH */
  474: 
  475:   return 0;
  476: }
  477: 
  478: int
  479: rl_clear_signals ()
  480: {
  481:   sighandler_cxt dummy;
  482: 
  483:   if (rl_catch_signals && signals_set_flag == 1)
  484:     {
  485:       sigemptyset (&dummy.sa_mask);
  486: 
  487:       /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
  488: 	 we should in theory not have to restore a handler where
  489: 	 old_xxx.sa_handler == SIG_IGN.  That's what rl_maybe_restore_sighandler
  490: 	 does.  Fewer system calls should reduce readline's per-line
  491: 	 overhead */
  492:       rl_maybe_restore_sighandler (SIGINT, &old_int);
  493:       rl_maybe_restore_sighandler (SIGTERM, &old_term);
  494:       rl_maybe_restore_sighandler (SIGHUP, &old_hup);
  495: #if defined (SIGQUIT)
  496:       rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
  497: #endif
  498: #if defined (SIGALRM)
  499:       rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
  500: #endif
  501: 
  502: #if defined (SIGTSTP)
  503:       rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
  504: #endif /* SIGTSTP */
  505: 
  506: #if defined (SIGTTOU)
  507:       rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
  508: #endif /* SIGTTOU */
  509: 
  510: #if defined (SIGTTIN)
  511:       rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
  512: #endif /* SIGTTIN */
  513: 
  514:       signals_set_flag = 0;
  515:     }
  516: 
  517: #if defined (SIGWINCH)
  518:   if (rl_catch_sigwinch && sigwinch_set_flag == 1)
  519:     {
  520:       sigemptyset (&dummy.sa_mask);
  521:       rl_sigaction (SIGWINCH, &old_winch, &dummy);
  522:       sigwinch_set_flag = 0;
  523:     }
  524: #endif
  525: 
  526:   return 0;
  527: }
  528: 
  529: /* Clean up the terminal and readline state after catching a signal, before
  530:    resending it to the calling application. */
  531: void
  532: rl_cleanup_after_signal ()
  533: {
  534:   _rl_clean_up_for_exit ();
  535:   if (rl_deprep_term_function)
  536:     (*rl_deprep_term_function) ();
  537:   rl_clear_pending_input ();
  538:   rl_clear_signals ();
  539: }
  540: 
  541: /* Reset the terminal and readline state after a signal handler returns. */
  542: void
  543: rl_reset_after_signal ()
  544: {
  545:   if (rl_prep_term_function)
  546:     (*rl_prep_term_function) (_rl_meta_flag);
  547:   rl_set_signals ();
  548: }
  549: 
  550: /* Free up the readline variable line state for the current line (undo list,
  551:    any partial history entry, any keyboard macros in progress, and any
  552:    numeric arguments in process) after catching a signal, before calling
  553:    rl_cleanup_after_signal(). */ 
  554: void
  555: rl_free_line_state ()
  556: {
  557:   register HIST_ENTRY *entry;
  558: 
  559:   rl_free_undo_list ();
  560: 
  561:   entry = current_history ();
  562:   if (entry)
  563:     entry->data = (char *)NULL;
  564: 
  565:   _rl_kill_kbd_macro ();
  566:   rl_clear_message ();
  567:   _rl_reset_argument ();
  568: }
  569: 
  570: #endif  /* HANDLE_SIGNALS */
  571: 
  572: /* **************************************************************** */
  573: /*								    */
  574: /*			   SIGINT Management			    */
  575: /*								    */
  576: /* **************************************************************** */
  577: 
  578: #if defined (HAVE_POSIX_SIGNALS)
  579: static sigset_t sigint_set, sigint_oset;
  580: static sigset_t sigwinch_set, sigwinch_oset;
  581: #else /* !HAVE_POSIX_SIGNALS */
  582: #  if defined (HAVE_BSD_SIGNALS)
  583: static int sigint_oldmask;
  584: static int sigwinch_oldmask;
  585: #  endif /* HAVE_BSD_SIGNALS */
  586: #endif /* !HAVE_POSIX_SIGNALS */
  587: 
  588: static int sigint_blocked;
  589: static int sigwinch_blocked;
  590: 
  591: /* Cause SIGINT to not be delivered until the corresponding call to
  592:    release_sigint(). */
  593: void
  594: _rl_block_sigint ()
  595: {
  596:   if (sigint_blocked)
  597:     return;
  598: 
  599:   sigint_blocked = 1;
  600: }
  601: 
  602: /* Allow SIGINT to be delivered. */
  603: void
  604: _rl_release_sigint ()
  605: {
  606:   if (sigint_blocked == 0)
  607:     return;
  608: 
  609:   sigint_blocked = 0;
  610:   RL_CHECK_SIGNALS ();
  611: }
  612: 
  613: /* Cause SIGWINCH to not be delivered until the corresponding call to
  614:    release_sigwinch(). */
  615: void
  616: _rl_block_sigwinch ()
  617: {
  618:   if (sigwinch_blocked)
  619:     return;
  620: 
  621: #if defined (SIGWINCH)
  622: 
  623: #if defined (HAVE_POSIX_SIGNALS)
  624:   sigemptyset (&sigwinch_set);
  625:   sigemptyset (&sigwinch_oset);
  626:   sigaddset (&sigwinch_set, SIGWINCH);
  627:   sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
  628: #else /* !HAVE_POSIX_SIGNALS */
  629: #  if defined (HAVE_BSD_SIGNALS)
  630:   sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
  631: #  else /* !HAVE_BSD_SIGNALS */
  632: #    if defined (HAVE_USG_SIGHOLD)
  633:   sighold (SIGWINCH);
  634: #    endif /* HAVE_USG_SIGHOLD */
  635: #  endif /* !HAVE_BSD_SIGNALS */
  636: #endif /* !HAVE_POSIX_SIGNALS */
  637: 
  638: #endif /* SIGWINCH */
  639: 
  640:   sigwinch_blocked = 1;
  641: }
  642: 
  643: /* Allow SIGWINCH to be delivered. */
  644: void
  645: _rl_release_sigwinch ()
  646: {
  647:   if (sigwinch_blocked == 0)
  648:     return;
  649: 
  650: #if defined (SIGWINCH)
  651: 
  652: #if defined (HAVE_POSIX_SIGNALS)
  653:   sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
  654: #else
  655: #  if defined (HAVE_BSD_SIGNALS)
  656:   sigsetmask (sigwinch_oldmask);
  657: #  else /* !HAVE_BSD_SIGNALS */
  658: #    if defined (HAVE_USG_SIGHOLD)
  659:   sigrelse (SIGWINCH);
  660: #    endif /* HAVE_USG_SIGHOLD */
  661: #  endif /* !HAVE_BSD_SIGNALS */
  662: #endif /* !HAVE_POSIX_SIGNALS */
  663: 
  664: #endif /* SIGWINCH */
  665: 
  666:   sigwinch_blocked = 0;
  667: }
  668: 
  669: /* **************************************************************** */
  670: /*								    */
  671: /*		Echoing special control characters		    */
  672: /*								    */
  673: /* **************************************************************** */
  674: void
  675: rl_echo_signal_char (sig)
  676:      int sig;
  677: {
  678:   char cstr[3];
  679:   int cslen, c;
  680: 
  681:   if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
  682:     return;
  683: 
  684:   switch (sig)
  685:     {
  686:     case SIGINT:  c = _rl_intr_char; break;
  687: #if defined (SIGQUIT)
  688:     case SIGQUIT: c = _rl_quit_char; break;
  689: #endif
  690: #if defined (SIGTSTP)
  691:     case SIGTSTP: c = _rl_susp_char; break;
  692: #endif
  693:     default: return;
  694:     }
  695: 
  696:   if (CTRL_CHAR (c) || c == RUBOUT)
  697:     {
  698:       cstr[0] = '^';
  699:       cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
  700:       cstr[cslen = 2] = '\0';
  701:     }
  702:   else
  703:     {
  704:       cstr[0] = c;
  705:       cstr[cslen = 1] = '\0';
  706:     }
  707: 
  708:   _rl_output_some_chars (cstr, cslen);
  709: }

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