* config/cygwin.cache: Prime mbstate_t.
[deliverable/binutils-gdb.git] / readline / signals.c
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
10 as published by the Free Software Foundation; either version 2, or
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,
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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 #if defined (HANDLE_SIGNALS)
44 /* Some standard library routines. */
45 #include "readline.h"
46 #include "history.h"
47
48 #include "rlprivate.h"
49
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
64 /* This typedef is equivalent to the one for Function; it allows us
65 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
66 typedef RETSIGTYPE SigHandler ();
67
68 #if defined (HAVE_POSIX_SIGNALS)
69 typedef struct sigaction sighandler_cxt;
70 # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
71 #else
72 typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
73 # define sigemptyset(m)
74 #endif /* !HAVE_POSIX_SIGNALS */
75
76 static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
77 static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
78
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. */
83 int rl_catch_signals = 1;
84
85 /* If non-zero, readline will install a signal handler for SIGWINCH. */
86 #ifdef SIGWINCH
87 int rl_catch_sigwinch = 1;
88 #endif
89
90 static int signals_set_flag;
91 #ifdef SIGWINCH
92 static int sigwinch_set_flag;
93 #endif
94
95 /* **************************************************************** */
96 /* */
97 /* Signal Handling */
98 /* */
99 /* **************************************************************** */
100
101 static sighandler_cxt old_int, old_term, old_alrm, old_quit;
102 #if defined (SIGTSTP)
103 static sighandler_cxt old_tstp, old_ttou, old_ttin;
104 #endif
105 #if defined (SIGWINCH)
106 static sighandler_cxt old_winch;
107 #endif
108
109 /* Readline signal handler functions. */
110
111 static RETSIGTYPE
112 rl_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
125 RL_SETSTATE(RL_STATE_SIGHANDLER);
126
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:
137 rl_free_line_state ();
138 /* FALLTHROUGH */
139
140 #if defined (SIGTSTP)
141 case SIGTSTP:
142 case SIGTTOU:
143 case SIGTTIN:
144 #endif /* SIGTSTP */
145 case SIGALRM:
146 case SIGTERM:
147 case SIGQUIT:
148 rl_cleanup_after_signal ();
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
159 #if defined (__EMX__)
160 signal (sig, SIG_ACK);
161 #endif
162
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
174 rl_reset_after_signal ();
175 }
176
177 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
178 SIGHANDLER_RETURN;
179 }
180
181 #if defined (SIGWINCH)
182 static RETSIGTYPE
183 rl_sigwinch_handler (sig)
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. */
195 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
196 #endif
197
198 RL_SETSTATE(RL_STATE_SIGHANDLER);
199 rl_resize_terminal ();
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
206 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
207 SIGHANDLER_RETURN;
208 }
209 #endif /* SIGWINCH */
210
211 /* Functions to manage signal handling. */
212
213 #if !defined (HAVE_POSIX_SIGNALS)
214 static int
215 rl_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(). */
227 static SigHandler *
228 rl_set_sighandler (sig, handler, ohandler)
229 int sig;
230 SigHandler *handler;
231 sighandler_cxt *ohandler;
232 {
233 sighandler_cxt old_handler;
234 #if defined (HAVE_POSIX_SIGNALS)
235 struct sigaction act;
236
237 act.sa_handler = handler;
238 act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
239 sigemptyset (&act.sa_mask);
240 sigemptyset (&ohandler->sa_mask);
241 sigaction (sig, &act, &old_handler);
242 #else
243 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
244 #endif /* !HAVE_POSIX_SIGNALS */
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
252 return (ohandler->sa_handler);
253 }
254
255 static void
256 rl_maybe_set_sighandler (sig, handler, ohandler)
257 int sig;
258 SigHandler *handler;
259 sighandler_cxt *ohandler;
260 {
261 sighandler_cxt dummy;
262 SigHandler *oh;
263
264 sigemptyset (&dummy.sa_mask);
265 oh = rl_set_sighandler (sig, handler, ohandler);
266 if (oh == (SigHandler *)SIG_IGN)
267 rl_sigaction (sig, ohandler, &dummy);
268 }
269
270 int
271 rl_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);
285 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
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);
292 #endif /* HAVE_POSIX_SIGNALS */
293
294 #if defined (SIGTSTP)
295 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
296 #endif /* SIGTSTP */
297
298 #if defined (SIGTTOU)
299 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
300 #endif /* SIGTTOU */
301
302 #if defined (SIGTTIN)
303 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
304 #endif /* SIGTTIN */
305
306 signals_set_flag = 1;
307 }
308
309 #if defined (SIGWINCH)
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 }
315 #endif /* SIGWINCH */
316
317 return 0;
318 }
319
320 int
321 rl_clear_signals ()
322 {
323 sighandler_cxt dummy;
324
325 if (rl_catch_signals && signals_set_flag == 1)
326 {
327 sigemptyset (&dummy.sa_mask);
328
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);
333
334 #if defined (SIGTSTP)
335 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
336 #endif /* SIGTSTP */
337
338 #if defined (SIGTTOU)
339 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
340 #endif /* SIGTTOU */
341
342 #if defined (SIGTTIN)
343 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
344 #endif /* SIGTTIN */
345
346 signals_set_flag = 0;
347 }
348
349 #if defined (SIGWINCH)
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 }
356 #endif
357
358 return 0;
359 }
360
361 /* Clean up the terminal and readline state after catching a signal, before
362 resending it to the calling application. */
363 void
364 rl_cleanup_after_signal ()
365 {
366 _rl_clean_up_for_exit ();
367 (*rl_deprep_term_function) ();
368 rl_clear_signals ();
369 rl_clear_pending_input ();
370 }
371
372 /* Reset the terminal and readline state after a signal handler returns. */
373 void
374 rl_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(). */
384 void
385 rl_free_line_state ()
386 {
387 register HIST_ENTRY *entry;
388
389 rl_free_undo_list ();
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
400 #endif /* HANDLE_SIGNALS */
This page took 0.038245 seconds and 4 git commands to generate.