Annotation of embedaddon/readline/signals.c, revision 1.1.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>