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

1.1       misho       1: /* signals.c -- signal handling support for readline. */
                      2: 
1.1.1.2 ! misho       3: /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
1.1       misho       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: 
1.1.1.2 ! misho     115: #if defined (HAVE_POSIX_SIGNALS)
        !           116: sigset_t _rl_orig_sigset;
        !           117: #endif /* !HAVE_POSIX_SIGNALS */
        !           118: 
1.1       misho     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: 
1.1.1.2 ! misho     138: /* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */
1.1       misho     139: RETSIGTYPE
1.1.1.2 ! misho     140: _rl_signal_handler (int sig)
1.1       misho     141: {
                    142:   _rl_caught_signal = 0;       /* XXX */
                    143: 
                    144: #if defined (SIGWINCH)
                    145:   if (sig == SIGWINCH)
                    146:     {
1.1.1.2 ! misho     147:       RL_SETSTATE(RL_STATE_SIGHANDLER);
        !           148: 
1.1       misho     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) ();
1.1.1.2 ! misho     156: 
        !           157:       RL_UNSETSTATE(RL_STATE_SIGHANDLER);
1.1       misho     158:     }
                    159:   else
                    160: #endif
                    161:     _rl_handle_signal (sig);
                    162: 
                    163:   SIGHANDLER_RETURN;
                    164: }
                    165: 
                    166: static RETSIGTYPE
1.1.1.2 ! misho     167: rl_signal_handler (int sig)
1.1       misho     168: {
1.1.1.2 ! misho     169:   _rl_caught_signal = sig;
1.1       misho     170:   SIGHANDLER_RETURN;
                    171: }
                    172: 
1.1.1.2 ! misho     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. */
1.1       misho     176: static RETSIGTYPE
1.1.1.2 ! misho     177: _rl_handle_signal (int sig)
1.1       misho     178: {
1.1.1.2 ! misho     179:   int block_sig;
        !           180: 
1.1       misho     181: #if defined (HAVE_POSIX_SIGNALS)
1.1.1.2 ! misho     182:   sigset_t set, oset;
1.1       misho     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:     }
1.1.1.2 ! misho     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: 
1.1       misho     222:   switch (sig)
                    223:     {
                    224:     case SIGINT:
                    225:       _rl_reset_completion_state ();
                    226:       rl_free_line_state ();
1.1.1.2 ! misho     227: #if defined (READLINE_CALLBACKS)
        !           228:       rl_callback_sigcleanup ();
        !           229: #endif
        !           230: 
1.1       misho     231:       /* FALLTHROUGH */
                    232: 
                    233: #if defined (SIGTSTP)
                    234:     case SIGTSTP:
                    235:     case SIGTTIN:
1.1.1.2 ! misho     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
1.1       misho     248: #endif /* SIGTSTP */
1.1.1.2 ! misho     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:
1.1       misho     262: #if defined (SIGALRM)
                    263:     case SIGALRM:
                    264: #endif
                    265: #if defined (SIGQUIT)
                    266:     case SIGQUIT:
                    267: #endif
1.1.1.2 ! misho     268: 
        !           269:       if (block_sig)
        !           270:        sigprocmask (SIG_BLOCK, &set, &oset);
        !           271: 
1.1       misho     272:       rl_echo_signal_char (sig);
                    273:       rl_cleanup_after_signal ();
                    274: 
1.1.1.2 ! misho     275:       /* At this point, the application's signal handler, if any, is the
        !           276:         current handler. */
        !           277: 
1.1       misho     278: #if defined (HAVE_POSIX_SIGNALS)
1.1.1.2 ! misho     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. */
1.1       misho     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 */
1.1.1.2 ! misho     298: #endif
1.1       misho     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: 
1.1.1.2 ! misho     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.  */
1.1       misho     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 */
1.1.1.2 ! misho     321: #endif
1.1       misho     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
1.1.1.2 ! misho     332: rl_sigwinch_handler (int sig)
1.1       misho     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
1.1.1.2 ! misho     363: rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh)
1.1       misho     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 *
1.1.1.2 ! misho     374: rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
1.1       misho     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
1.1.1.2 ! misho     405: rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
1.1       misho     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
1.1.1.2 ! misho     422: rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler)
1.1       misho     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
1.1.1.2 ! misho     433: rl_set_signals (void)
1.1       misho     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);
1.1.1.2 ! misho     449: #if defined (SIGHUP)
1.1       misho     450:       sigaddset (&bset, SIGHUP);
1.1.1.2 ! misho     451: #endif
1.1       misho     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)
1.1.1.2 ! misho     474:       sigemptyset (&_rl_orig_sigset);
        !           475:       sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset);
1.1       misho     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);
1.1.1.2 ! misho     480: #if defined (SIGHUP)
1.1       misho     481:       rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
1.1.1.2 ! misho     482: #endif
1.1       misho     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)
1.1.1.2 ! misho     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);
1.1       misho     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
1.1.1.2 ! misho     539: rl_clear_signals (void)
1.1       misho     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);
1.1.1.2 ! misho     552: #if defined (SIGHUP)
1.1       misho     553:       rl_maybe_restore_sighandler (SIGHUP, &old_hup);
1.1.1.2 ! misho     554: #endif
1.1       misho     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
1.1.1.2 ! misho     592: rl_cleanup_after_signal (void)
1.1       misho     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
1.1.1.2 ! misho     603: rl_reset_after_signal (void)
1.1       misho     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
1.1.1.2 ! misho     615: rl_free_line_state (void)
1.1       misho     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: 
1.1.1.2 ! misho     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: }
1.1       misho     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
1.1.1.2 ! misho     665: _rl_block_sigint (void)
1.1       misho     666: {
                    667:   if (sigint_blocked)
                    668:     return;
                    669: 
                    670:   sigint_blocked = 1;
                    671: }
                    672: 
                    673: /* Allow SIGINT to be delivered. */
                    674: void
1.1.1.2 ! misho     675: _rl_release_sigint (void)
1.1       misho     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
1.1.1.2 ! misho     687: _rl_block_sigwinch (void)
1.1       misho     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
1.1.1.2 ! misho     716: _rl_release_sigwinch (void)
1.1       misho     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
1.1.1.2 ! misho     746: rl_echo_signal_char (int sig)
1.1       misho     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>