Import of readline 4.3.
[deliverable/binutils-gdb.git] / readline / signals.c
CommitLineData
d60d9f65
SS
1/* signals.c -- signal handling support for readline. */
2
3/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
7
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
1b17e766 10 as published by the Free Software Foundation; either version 2, or
d60d9f65
SS
11 (at your option) any later version.
12
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.
17
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,
1b17e766 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
d60d9f65
SS
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
d60d9f65
SS
43#if defined (HANDLE_SIGNALS)
44/* Some standard library routines. */
45#include "readline.h"
46#include "history.h"
47
1b17e766
EZ
48#include "rlprivate.h"
49
d60d9f65
SS
50#if !defined (RETSIGTYPE)
51# if defined (VOID_SIGHANDLER)
52# define RETSIGTYPE void
53# else
54# define RETSIGTYPE int
55# endif /* !VOID_SIGHANDLER */
56#endif /* !RETSIGTYPE */
57
58#if defined (VOID_SIGHANDLER)
59# define SIGHANDLER_RETURN return
60#else
61# define SIGHANDLER_RETURN return (0)
62#endif
63
9255ee31 64/* This typedef is equivalent to the one for Function; it allows us
d60d9f65
SS
65 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
66typedef RETSIGTYPE SigHandler ();
67
1b17e766
EZ
68#if defined (HAVE_POSIX_SIGNALS)
69typedef struct sigaction sighandler_cxt;
70# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
71#else
72typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
73# define sigemptyset(m)
74#endif /* !HAVE_POSIX_SIGNALS */
c862e87b 75
9255ee31
EZ
76static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
77static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
d60d9f65 78
c862e87b
JM
79/* Exported variables for use by applications. */
80
81/* If non-zero, readline will install its own signal handlers for
82 SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
83int rl_catch_signals = 1;
84
85/* If non-zero, readline will install a signal handler for SIGWINCH. */
86#ifdef SIGWINCH
87int rl_catch_sigwinch = 1;
88#endif
89
90static int signals_set_flag;
a66f60a2 91#ifdef SIGWINCH
c862e87b 92static int sigwinch_set_flag;
a66f60a2 93#endif
c862e87b 94
d60d9f65
SS
95/* **************************************************************** */
96/* */
97/* Signal Handling */
98/* */
99/* **************************************************************** */
100
c862e87b
JM
101static sighandler_cxt old_int, old_term, old_alrm, old_quit;
102#if defined (SIGTSTP)
d60d9f65 103static sighandler_cxt old_tstp, old_ttou, old_ttin;
d60d9f65 104#endif
d60d9f65
SS
105#if defined (SIGWINCH)
106static sighandler_cxt old_winch;
107#endif
108
109/* Readline signal handler functions. */
110
111static RETSIGTYPE
112rl_signal_handler (sig)
113 int sig;
114{
115#if defined (HAVE_POSIX_SIGNALS)
116 sigset_t set;
117#else /* !HAVE_POSIX_SIGNALS */
118# if defined (HAVE_BSD_SIGNALS)
119 long omask;
120# else /* !HAVE_BSD_SIGNALS */
121 sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
122# endif /* !HAVE_BSD_SIGNALS */
123#endif /* !HAVE_POSIX_SIGNALS */
124
9255ee31
EZ
125 RL_SETSTATE(RL_STATE_SIGHANDLER);
126
d60d9f65
SS
127#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
128 /* Since the signal will not be blocked while we are in the signal
129 handler, ignore it until rl_clear_signals resets the catcher. */
130 if (sig == SIGINT || sig == SIGALRM)
131 rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
132#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
133
134 switch (sig)
135 {
136 case SIGINT:
c862e87b
JM
137 rl_free_line_state ();
138 /* FALLTHROUGH */
d60d9f65
SS
139
140#if defined (SIGTSTP)
141 case SIGTSTP:
142 case SIGTTOU:
143 case SIGTTIN:
144#endif /* SIGTSTP */
145 case SIGALRM:
146 case SIGTERM:
c862e87b
JM
147 case SIGQUIT:
148 rl_cleanup_after_signal ();
d60d9f65
SS
149
150#if defined (HAVE_POSIX_SIGNALS)
151 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
152 sigdelset (&set, sig);
153#else /* !HAVE_POSIX_SIGNALS */
154# if defined (HAVE_BSD_SIGNALS)
155 omask = sigblock (0);
156# endif /* HAVE_BSD_SIGNALS */
157#endif /* !HAVE_POSIX_SIGNALS */
158
1b17e766
EZ
159#if defined (__EMX__)
160 signal (sig, SIG_ACK);
161#endif
162
d60d9f65
SS
163 kill (getpid (), sig);
164
165 /* Let the signal that we just sent through. */
166#if defined (HAVE_POSIX_SIGNALS)
167 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
168#else /* !HAVE_POSIX_SIGNALS */
169# if defined (HAVE_BSD_SIGNALS)
170 sigsetmask (omask & ~(sigmask (sig)));
171# endif /* HAVE_BSD_SIGNALS */
172#endif /* !HAVE_POSIX_SIGNALS */
173
c862e87b 174 rl_reset_after_signal ();
d60d9f65
SS
175 }
176
9255ee31 177 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
d60d9f65
SS
178 SIGHANDLER_RETURN;
179}
180
181#if defined (SIGWINCH)
182static RETSIGTYPE
c862e87b 183rl_sigwinch_handler (sig)
d60d9f65
SS
184 int sig;
185{
186 SigHandler *oh;
187
188#if defined (MUST_REINSTALL_SIGHANDLERS)
189 sighandler_cxt dummy_winch;
190
191 /* We don't want to change old_winch -- it holds the state of SIGWINCH
192 disposition set by the calling application. We need this state
193 because we call the application's SIGWINCH handler after updating
194 our own idea of the screen size. */
c862e87b 195 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
d60d9f65
SS
196#endif
197
9255ee31 198 RL_SETSTATE(RL_STATE_SIGHANDLER);
c862e87b 199 rl_resize_terminal ();
d60d9f65
SS
200
201 /* If another sigwinch handler has been installed, call it. */
202 oh = (SigHandler *)old_winch.sa_handler;
203 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
204 (*oh) (sig);
205
9255ee31 206 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
d60d9f65
SS
207 SIGHANDLER_RETURN;
208}
209#endif /* SIGWINCH */
210
211/* Functions to manage signal handling. */
212
213#if !defined (HAVE_POSIX_SIGNALS)
214static int
215rl_sigaction (sig, nh, oh)
216 int sig;
217 sighandler_cxt *nh, *oh;
218{
219 oh->sa_handler = signal (sig, nh->sa_handler);
220 return 0;
221}
222#endif /* !HAVE_POSIX_SIGNALS */
223
224/* Set up a readline-specific signal handler, saving the old signal
225 information in OHANDLER. Return the old signal handler, like
226 signal(). */
227static SigHandler *
228rl_set_sighandler (sig, handler, ohandler)
229 int sig;
230 SigHandler *handler;
231 sighandler_cxt *ohandler;
232{
1b17e766 233 sighandler_cxt old_handler;
d60d9f65
SS
234#if defined (HAVE_POSIX_SIGNALS)
235 struct sigaction act;
236
237 act.sa_handler = handler;
9255ee31 238 act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
d60d9f65
SS
239 sigemptyset (&act.sa_mask);
240 sigemptyset (&ohandler->sa_mask);
1b17e766 241 sigaction (sig, &act, &old_handler);
d60d9f65 242#else
1b17e766 243 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
d60d9f65 244#endif /* !HAVE_POSIX_SIGNALS */
1b17e766
EZ
245
246 /* XXX -- assume we have memcpy */
247 /* If rl_set_signals is called twice in a row, don't set the old handler to
248 rl_signal_handler, because that would cause infinite recursion. */
249 if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
250 memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
251
d60d9f65
SS
252 return (ohandler->sa_handler);
253}
254
c862e87b
JM
255static void
256rl_maybe_set_sighandler (sig, handler, ohandler)
257 int sig;
258 SigHandler *handler;
259 sighandler_cxt *ohandler;
d60d9f65
SS
260{
261 sighandler_cxt dummy;
262 SigHandler *oh;
263
d60d9f65 264 sigemptyset (&dummy.sa_mask);
c862e87b 265 oh = rl_set_sighandler (sig, handler, ohandler);
d60d9f65 266 if (oh == (SigHandler *)SIG_IGN)
c862e87b
JM
267 rl_sigaction (sig, ohandler, &dummy);
268}
d60d9f65 269
c862e87b
JM
270int
271rl_set_signals ()
272{
273 sighandler_cxt dummy;
274 SigHandler *oh;
275
276 if (rl_catch_signals && signals_set_flag == 0)
277 {
278 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
279 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
280 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
281
282 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
283 if (oh == (SigHandler *)SIG_IGN)
284 rl_sigaction (SIGALRM, &old_alrm, &dummy);
d60d9f65 285#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
c862e87b
JM
286 /* If the application using readline has already installed a signal
287 handler with SA_RESTART, SIGALRM will cause reads to be restarted
288 automatically, so readline should just get out of the way. Since
289 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
290 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
291 rl_sigaction (SIGALRM, &old_alrm, &dummy);
d60d9f65
SS
292#endif /* HAVE_POSIX_SIGNALS */
293
d60d9f65 294#if defined (SIGTSTP)
c862e87b 295 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
d60d9f65
SS
296#endif /* SIGTSTP */
297
298#if defined (SIGTTOU)
c862e87b 299 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
d60d9f65
SS
300#endif /* SIGTTOU */
301
c862e87b
JM
302#if defined (SIGTTIN)
303 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
304#endif /* SIGTTIN */
d60d9f65 305
c862e87b
JM
306 signals_set_flag = 1;
307 }
d60d9f65
SS
308
309#if defined (SIGWINCH)
c862e87b
JM
310 if (rl_catch_sigwinch && sigwinch_set_flag == 0)
311 {
312 rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
313 sigwinch_set_flag = 1;
314 }
d60d9f65
SS
315#endif /* SIGWINCH */
316
317 return 0;
318}
319
320int
321rl_clear_signals ()
322{
323 sighandler_cxt dummy;
324
c862e87b
JM
325 if (rl_catch_signals && signals_set_flag == 1)
326 {
327 sigemptyset (&dummy.sa_mask);
d60d9f65 328
c862e87b
JM
329 rl_sigaction (SIGINT, &old_int, &dummy);
330 rl_sigaction (SIGTERM, &old_term, &dummy);
331 rl_sigaction (SIGQUIT, &old_quit, &dummy);
332 rl_sigaction (SIGALRM, &old_alrm, &dummy);
d60d9f65
SS
333
334#if defined (SIGTSTP)
c862e87b
JM
335 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
336#endif /* SIGTSTP */
d60d9f65
SS
337
338#if defined (SIGTTOU)
c862e87b 339 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
d60d9f65
SS
340#endif /* SIGTTOU */
341
c862e87b
JM
342#if defined (SIGTTIN)
343 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
344#endif /* SIGTTIN */
d60d9f65 345
c862e87b
JM
346 signals_set_flag = 0;
347 }
d60d9f65
SS
348
349#if defined (SIGWINCH)
c862e87b
JM
350 if (rl_catch_sigwinch && sigwinch_set_flag == 1)
351 {
352 sigemptyset (&dummy.sa_mask);
353 rl_sigaction (SIGWINCH, &old_winch, &dummy);
354 sigwinch_set_flag = 0;
355 }
d60d9f65
SS
356#endif
357
358 return 0;
359}
c862e87b
JM
360
361/* Clean up the terminal and readline state after catching a signal, before
362 resending it to the calling application. */
363void
364rl_cleanup_after_signal ()
365{
366 _rl_clean_up_for_exit ();
367 (*rl_deprep_term_function) ();
368 rl_clear_signals ();
9255ee31 369 rl_clear_pending_input ();
c862e87b
JM
370}
371
372/* Reset the terminal and readline state after a signal handler returns. */
373void
374rl_reset_after_signal ()
375{
376 (*rl_prep_term_function) (_rl_meta_flag);
377 rl_set_signals ();
378}
379
380/* Free up the readline variable line state for the current line (undo list,
381 any partial history entry, any keyboard macros in progress, and any
382 numeric arguments in process) after catching a signal, before calling
383 rl_cleanup_after_signal(). */
384void
385rl_free_line_state ()
386{
387 register HIST_ENTRY *entry;
388
9255ee31 389 rl_free_undo_list ();
c862e87b
JM
390
391 entry = current_history ();
392 if (entry)
393 entry->data = (char *)NULL;
394
395 _rl_kill_kbd_macro ();
396 rl_clear_message ();
397 _rl_init_argument ();
398}
399
d60d9f65 400#endif /* HANDLE_SIGNALS */
This page took 0.187398 seconds and 4 git commands to generate.