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>