Annotation of embedaddon/readline/signals.c, revision 1.1

1.1     ! misho       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>