1 /* signals.c -- signal handling support for readline. */
3 /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
8 The GNU Readline Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 1, or
11 (at your option) any later version.
13 The GNU Readline Library is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #define READLINE_LIBRARY
24 #if defined (HAVE_CONFIG_H)
28 #include <stdio.h> /* Just for NULL. Yuck. */
29 #include <sys/types.h>
32 #if defined (HAVE_UNISTD_H)
34 #endif /* HAVE_UNISTD_H */
36 /* System-specific feature definitions and include files. */
39 #if defined (GWINSZ_IN_SYS_IOCTL)
40 # include <sys/ioctl.h>
41 #endif /* GWINSZ_IN_SYS_IOCTL */
43 #if defined (__GO32__)
44 # undef HANDLE_SIGNALS
47 #if defined (HANDLE_SIGNALS)
48 /* Some standard library routines. */
52 extern int readline_echoing_p;
53 extern int rl_pending_input;
54 extern int _rl_meta_flag;
56 extern void free_undo_list ();
57 extern void _rl_get_screen_size ();
58 extern void _rl_redisplay_after_sigwinch ();
59 extern void _rl_clean_up_for_exit ();
60 extern void _rl_kill_kbd_macro ();
61 extern void _rl_init_argument ();
62 extern void rl_deprep_terminal (), rl_prep_terminal ();
64 #if !defined (RETSIGTYPE)
65 # if defined (VOID_SIGHANDLER)
66 # define RETSIGTYPE void
68 # define RETSIGTYPE int
69 # endif /* !VOID_SIGHANDLER */
70 #endif /* !RETSIGTYPE */
72 #if defined (VOID_SIGHANDLER)
73 # define SIGHANDLER_RETURN return
75 # define SIGHANDLER_RETURN return (0)
78 /* This typedef is equivalant to the one for Function; it allows us
79 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
80 typedef RETSIGTYPE SigHandler ();
82 static SigHandler *rl_set_sighandler ();
84 /* **************************************************************** */
88 /* **************************************************************** */
90 #if defined (HAVE_POSIX_SIGNALS)
91 typedef struct sigaction sighandler_cxt;
92 # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
94 typedef struct { SigHandler *sa_handler; } sighandler_cxt;
95 # define sigemptyset(m)
96 #endif /* !HAVE_POSIX_SIGNALS */
98 static sighandler_cxt old_int, old_alrm;
101 static sighandler_cxt old_tstp, old_ttou, old_ttin, old_term;
104 #if defined (SIGWINCH)
105 static sighandler_cxt old_winch;
108 /* Readline signal handler functions. */
111 rl_signal_handler (sig)
114 #if defined (HAVE_POSIX_SIGNALS)
116 #else /* !HAVE_POSIX_SIGNALS */
117 # if defined (HAVE_BSD_SIGNALS)
119 # endif /* HAVE_BSD_SIGNALS */
120 #endif /* !HAVE_POSIX_SIGNALS */
122 #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
123 /* Since the signal will not be blocked while we are in the signal
124 handler, ignore it until rl_clear_signals resets the catcher. */
125 if (sig == SIGINT || sig == SIGALRM)
126 rl_set_sighandler (sig, SIG_IGN, (sighandler_cxt *)NULL);
127 #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
133 register HIST_ENTRY *entry;
137 entry = current_history ();
139 entry->data = (char *)NULL;
141 _rl_kill_kbd_macro ();
143 _rl_init_argument ();
145 #if defined (SIGTSTP)
152 _rl_clean_up_for_exit ();
153 (*rl_deprep_term_function) ();
155 rl_pending_input = 0;
157 #if defined (HAVE_POSIX_SIGNALS)
158 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
159 sigdelset (&set, sig);
160 #else /* !HAVE_POSIX_SIGNALS */
161 # if defined (HAVE_BSD_SIGNALS)
162 omask = sigblock (0);
163 # endif /* HAVE_BSD_SIGNALS */
164 #endif /* !HAVE_POSIX_SIGNALS */
166 kill (getpid (), sig);
168 /* Let the signal that we just sent through. */
169 #if defined (HAVE_POSIX_SIGNALS)
170 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
171 #else /* !HAVE_POSIX_SIGNALS */
172 # if defined (HAVE_BSD_SIGNALS)
173 sigsetmask (omask & ~(sigmask (sig)));
174 # endif /* HAVE_BSD_SIGNALS */
175 #endif /* !HAVE_POSIX_SIGNALS */
177 (*rl_prep_term_function) (_rl_meta_flag);
184 #if defined (SIGWINCH)
186 rl_handle_sigwinch (sig)
191 if (readline_echoing_p)
193 _rl_get_screen_size (fileno (rl_instream), 1);
194 _rl_redisplay_after_sigwinch ();
197 /* If another sigwinch handler has been installed, call it. */
198 oh = (SigHandler *)old_winch.sa_handler;
199 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
204 #endif /* SIGWINCH */
206 /* Functions to manage signal handling. */
208 #if !defined (HAVE_POSIX_SIGNALS)
210 rl_sigaction (sig, nh, oh)
212 sighandler_cxt *nh, *oh;
214 oh->sa_handler = signal (sig, nh->sa_handler);
217 #endif /* !HAVE_POSIX_SIGNALS */
219 /* Set up a readline-specific signal handler, saving the old signal
220 information in OHANDLER. Return the old signal handler, like
223 rl_set_sighandler (sig, handler, ohandler)
226 sighandler_cxt *ohandler;
228 #if defined (HAVE_POSIX_SIGNALS)
229 struct sigaction act;
231 act.sa_handler = handler;
233 sigemptyset (&act.sa_mask);
234 sigemptyset (&ohandler->sa_mask);
235 sigaction (sig, &act, ohandler);
237 ohandler->sa_handler = (SigHandler *)signal (sig, handler);
238 #endif /* !HAVE_POSIX_SIGNALS */
239 return (ohandler->sa_handler);
245 sighandler_cxt dummy;
248 #if defined (HAVE_POSIX_SIGNALS)
249 sigemptyset (&dummy.sa_mask);
252 oh = rl_set_sighandler (SIGINT, rl_signal_handler, &old_int);
253 if (oh == (SigHandler *)SIG_IGN)
254 rl_sigaction (SIGINT, &old_int, &dummy);
256 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
257 if (oh == (SigHandler *)SIG_IGN)
258 rl_sigaction (SIGALRM, &old_alrm, &dummy);
259 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
260 /* If the application using readline has already installed a signal
261 handler with SA_RESTART, SIGALRM will cause reads to be restarted
262 automatically, so readline should just get out of the way. Since
263 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
264 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
265 rl_sigaction (SIGALRM, &old_alrm, &dummy);
266 #endif /* HAVE_POSIX_SIGNALS */
270 #if defined (SIGTSTP)
271 oh = rl_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
272 if (oh == (SigHandler *)SIG_IGN)
273 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
275 oh = (SigHandler *)NULL;
278 #if defined (SIGTTOU)
279 rl_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
280 rl_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
282 if (oh == (SigHandler *)SIG_IGN)
284 rl_set_sighandler (SIGTTOU, SIG_IGN, &dummy);
285 rl_set_sighandler (SIGTTIN, SIG_IGN, &dummy);
289 /* Handle SIGTERM if we're not being compiled as part of bash. */
290 rl_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
293 #if defined (SIGWINCH)
294 rl_set_sighandler (SIGWINCH, rl_handle_sigwinch, &old_winch);
295 #endif /* SIGWINCH */
303 sighandler_cxt dummy;
305 #if defined (HAVE_POSIX_SIGNALS)
306 sigemptyset (&dummy.sa_mask);
309 rl_sigaction (SIGINT, &old_int, &dummy);
310 rl_sigaction (SIGALRM, &old_alrm, &dummy);
314 #if defined (SIGTSTP)
315 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
318 #if defined (SIGTTOU)
319 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
320 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
323 rl_sigaction (SIGTERM, &old_term, &dummy);
327 #if defined (SIGWINCH)
328 sigemptyset (&dummy.sa_mask);
329 rl_sigaction (SIGWINCH, &old_winch, &dummy);
334 #endif /* HANDLE_SIGNALS */