Fix typos in ChangeLog
[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. */
430b7832
MM
130 if (sig == SIGINT
131#ifdef SIGALRM
132 || sig == SIGALRM
133#endif
134 )
d60d9f65
SS
135 rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
136#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
137
138 switch (sig)
139 {
140 case SIGINT:
c862e87b
JM
141 rl_free_line_state ();
142 /* FALLTHROUGH */
d60d9f65
SS
143
144#if defined (SIGTSTP)
145 case SIGTSTP:
146 case SIGTTOU:
147 case SIGTTIN:
148#endif /* SIGTSTP */
430b7832 149#ifdef SIGALRM
d60d9f65 150 case SIGALRM:
430b7832 151#endif
d60d9f65 152 case SIGTERM:
430b7832 153#ifdef SIGQUIT
c862e87b 154 case SIGQUIT:
430b7832 155#endif
c862e87b 156 rl_cleanup_after_signal ();
d60d9f65
SS
157
158#if defined (HAVE_POSIX_SIGNALS)
159 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
160 sigdelset (&set, sig);
161#else /* !HAVE_POSIX_SIGNALS */
162# if defined (HAVE_BSD_SIGNALS)
163 omask = sigblock (0);
164# endif /* HAVE_BSD_SIGNALS */
165#endif /* !HAVE_POSIX_SIGNALS */
166
1b17e766
EZ
167#if defined (__EMX__)
168 signal (sig, SIG_ACK);
169#endif
170
430b7832
MM
171 /* If we have the POSIX kill function, use it; otherwise, fall
172 back to the ISO C raise function. (Windows is an example of
173 a platform that has raise, but not kill.) */
174#ifdef HAVE_KILL
d60d9f65 175 kill (getpid (), sig);
430b7832
MM
176#else
177 raise (sig);
178#endif
d60d9f65
SS
179
180 /* Let the signal that we just sent through. */
181#if defined (HAVE_POSIX_SIGNALS)
182 sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
183#else /* !HAVE_POSIX_SIGNALS */
184# if defined (HAVE_BSD_SIGNALS)
185 sigsetmask (omask & ~(sigmask (sig)));
186# endif /* HAVE_BSD_SIGNALS */
187#endif /* !HAVE_POSIX_SIGNALS */
188
c862e87b 189 rl_reset_after_signal ();
d60d9f65
SS
190 }
191
9255ee31 192 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
d60d9f65
SS
193 SIGHANDLER_RETURN;
194}
195
196#if defined (SIGWINCH)
197static RETSIGTYPE
c862e87b 198rl_sigwinch_handler (sig)
d60d9f65
SS
199 int sig;
200{
201 SigHandler *oh;
202
203#if defined (MUST_REINSTALL_SIGHANDLERS)
204 sighandler_cxt dummy_winch;
205
206 /* We don't want to change old_winch -- it holds the state of SIGWINCH
207 disposition set by the calling application. We need this state
208 because we call the application's SIGWINCH handler after updating
209 our own idea of the screen size. */
c862e87b 210 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
d60d9f65
SS
211#endif
212
9255ee31 213 RL_SETSTATE(RL_STATE_SIGHANDLER);
c862e87b 214 rl_resize_terminal ();
d60d9f65
SS
215
216 /* If another sigwinch handler has been installed, call it. */
217 oh = (SigHandler *)old_winch.sa_handler;
218 if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
219 (*oh) (sig);
220
9255ee31 221 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
d60d9f65
SS
222 SIGHANDLER_RETURN;
223}
224#endif /* SIGWINCH */
225
226/* Functions to manage signal handling. */
227
228#if !defined (HAVE_POSIX_SIGNALS)
229static int
230rl_sigaction (sig, nh, oh)
231 int sig;
232 sighandler_cxt *nh, *oh;
233{
234 oh->sa_handler = signal (sig, nh->sa_handler);
235 return 0;
236}
237#endif /* !HAVE_POSIX_SIGNALS */
238
239/* Set up a readline-specific signal handler, saving the old signal
240 information in OHANDLER. Return the old signal handler, like
241 signal(). */
242static SigHandler *
243rl_set_sighandler (sig, handler, ohandler)
244 int sig;
245 SigHandler *handler;
246 sighandler_cxt *ohandler;
247{
1b17e766 248 sighandler_cxt old_handler;
d60d9f65
SS
249#if defined (HAVE_POSIX_SIGNALS)
250 struct sigaction act;
251
252 act.sa_handler = handler;
9255ee31 253 act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
d60d9f65
SS
254 sigemptyset (&act.sa_mask);
255 sigemptyset (&ohandler->sa_mask);
1b17e766 256 sigaction (sig, &act, &old_handler);
d60d9f65 257#else
1b17e766 258 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
d60d9f65 259#endif /* !HAVE_POSIX_SIGNALS */
1b17e766
EZ
260
261 /* XXX -- assume we have memcpy */
262 /* If rl_set_signals is called twice in a row, don't set the old handler to
263 rl_signal_handler, because that would cause infinite recursion. */
264 if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
265 memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
266
d60d9f65
SS
267 return (ohandler->sa_handler);
268}
269
c862e87b
JM
270static void
271rl_maybe_set_sighandler (sig, handler, ohandler)
272 int sig;
273 SigHandler *handler;
274 sighandler_cxt *ohandler;
d60d9f65
SS
275{
276 sighandler_cxt dummy;
277 SigHandler *oh;
278
d60d9f65 279 sigemptyset (&dummy.sa_mask);
c862e87b 280 oh = rl_set_sighandler (sig, handler, ohandler);
d60d9f65 281 if (oh == (SigHandler *)SIG_IGN)
c862e87b
JM
282 rl_sigaction (sig, ohandler, &dummy);
283}
d60d9f65 284
c862e87b
JM
285int
286rl_set_signals ()
287{
288 sighandler_cxt dummy;
289 SigHandler *oh;
290
291 if (rl_catch_signals && signals_set_flag == 0)
292 {
293 rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
294 rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
430b7832 295#ifdef SIGQUIT
c862e87b 296 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
430b7832 297#endif
c862e87b 298
430b7832 299#ifdef SIGALRM
c862e87b
JM
300 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
301 if (oh == (SigHandler *)SIG_IGN)
302 rl_sigaction (SIGALRM, &old_alrm, &dummy);
d60d9f65 303#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
c862e87b
JM
304 /* If the application using readline has already installed a signal
305 handler with SA_RESTART, SIGALRM will cause reads to be restarted
306 automatically, so readline should just get out of the way. Since
307 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
308 if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
309 rl_sigaction (SIGALRM, &old_alrm, &dummy);
d60d9f65 310#endif /* HAVE_POSIX_SIGNALS */
430b7832 311#endif /* SIGALRM */
d60d9f65 312
d60d9f65 313#if defined (SIGTSTP)
c862e87b 314 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
d60d9f65
SS
315#endif /* SIGTSTP */
316
317#if defined (SIGTTOU)
c862e87b 318 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
d60d9f65
SS
319#endif /* SIGTTOU */
320
c862e87b
JM
321#if defined (SIGTTIN)
322 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
323#endif /* SIGTTIN */
d60d9f65 324
c862e87b
JM
325 signals_set_flag = 1;
326 }
d60d9f65
SS
327
328#if defined (SIGWINCH)
c862e87b
JM
329 if (rl_catch_sigwinch && sigwinch_set_flag == 0)
330 {
331 rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
332 sigwinch_set_flag = 1;
333 }
d60d9f65
SS
334#endif /* SIGWINCH */
335
336 return 0;
337}
338
339int
340rl_clear_signals ()
341{
342 sighandler_cxt dummy;
343
c862e87b
JM
344 if (rl_catch_signals && signals_set_flag == 1)
345 {
346 sigemptyset (&dummy.sa_mask);
d60d9f65 347
c862e87b
JM
348 rl_sigaction (SIGINT, &old_int, &dummy);
349 rl_sigaction (SIGTERM, &old_term, &dummy);
430b7832 350#ifdef SIGQUIT
c862e87b 351 rl_sigaction (SIGQUIT, &old_quit, &dummy);
430b7832
MM
352#endif
353#ifdef SIGALRM
c862e87b 354 rl_sigaction (SIGALRM, &old_alrm, &dummy);
430b7832 355#endif
d60d9f65
SS
356
357#if defined (SIGTSTP)
c862e87b
JM
358 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
359#endif /* SIGTSTP */
d60d9f65
SS
360
361#if defined (SIGTTOU)
c862e87b 362 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
d60d9f65
SS
363#endif /* SIGTTOU */
364
c862e87b
JM
365#if defined (SIGTTIN)
366 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
367#endif /* SIGTTIN */
d60d9f65 368
c862e87b
JM
369 signals_set_flag = 0;
370 }
d60d9f65
SS
371
372#if defined (SIGWINCH)
c862e87b
JM
373 if (rl_catch_sigwinch && sigwinch_set_flag == 1)
374 {
375 sigemptyset (&dummy.sa_mask);
376 rl_sigaction (SIGWINCH, &old_winch, &dummy);
377 sigwinch_set_flag = 0;
378 }
d60d9f65
SS
379#endif
380
381 return 0;
382}
c862e87b
JM
383
384/* Clean up the terminal and readline state after catching a signal, before
385 resending it to the calling application. */
386void
387rl_cleanup_after_signal ()
388{
389 _rl_clean_up_for_exit ();
390 (*rl_deprep_term_function) ();
391 rl_clear_signals ();
9255ee31 392 rl_clear_pending_input ();
c862e87b
JM
393}
394
395/* Reset the terminal and readline state after a signal handler returns. */
396void
397rl_reset_after_signal ()
398{
399 (*rl_prep_term_function) (_rl_meta_flag);
400 rl_set_signals ();
401}
402
403/* Free up the readline variable line state for the current line (undo list,
404 any partial history entry, any keyboard macros in progress, and any
405 numeric arguments in process) after catching a signal, before calling
406 rl_cleanup_after_signal(). */
407void
408rl_free_line_state ()
409{
410 register HIST_ENTRY *entry;
411
9255ee31 412 rl_free_undo_list ();
c862e87b
JM
413
414 entry = current_history ();
415 if (entry)
416 entry->data = (char *)NULL;
417
418 _rl_kill_kbd_macro ();
419 rl_clear_message ();
420 _rl_init_argument ();
421}
422
d60d9f65 423#endif /* HANDLE_SIGNALS */
This page took 0.279194 seconds and 4 git commands to generate.