* input.c (rl_getc): Use getch to read console input on
[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
131 #ifdef SIGALRM
132 || sig == SIGALRM
133 #endif
134 )
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:
141 rl_free_line_state ();
142 /* FALLTHROUGH */
143
144 #if defined (SIGTSTP)
145 case SIGTSTP:
146 case SIGTTOU:
147 case SIGTTIN:
148 #endif /* SIGTSTP */
149 #ifdef SIGALRM
150 case SIGALRM:
151 #endif
152 case SIGTERM:
153 #ifdef SIGQUIT
154 case SIGQUIT:
155 #endif
156 rl_cleanup_after_signal ();
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
167 #if defined (__EMX__)
168 signal (sig, SIG_ACK);
169 #endif
170
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
175 kill (getpid (), sig);
176 #else
177 raise (sig);
178 #endif
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
189 rl_reset_after_signal ();
190 }
191
192 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
193 SIGHANDLER_RETURN;
194 }
195
196 #if defined (SIGWINCH)
197 static RETSIGTYPE
198 rl_sigwinch_handler (sig)
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. */
210 rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
211 #endif
212
213 RL_SETSTATE(RL_STATE_SIGHANDLER);
214 rl_resize_terminal ();
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
221 RL_UNSETSTATE(RL_STATE_SIGHANDLER);
222 SIGHANDLER_RETURN;
223 }
224 #endif /* SIGWINCH */
225
226 /* Functions to manage signal handling. */
227
228 #if !defined (HAVE_POSIX_SIGNALS)
229 static int
230 rl_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(). */
242 static SigHandler *
243 rl_set_sighandler (sig, handler, ohandler)
244 int sig;
245 SigHandler *handler;
246 sighandler_cxt *ohandler;
247 {
248 sighandler_cxt old_handler;
249 #if defined (HAVE_POSIX_SIGNALS)
250 struct sigaction act;
251
252 act.sa_handler = handler;
253 act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
254 sigemptyset (&act.sa_mask);
255 sigemptyset (&ohandler->sa_mask);
256 sigaction (sig, &act, &old_handler);
257 #else
258 old_handler.sa_handler = (SigHandler *)signal (sig, handler);
259 #endif /* !HAVE_POSIX_SIGNALS */
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
267 return (ohandler->sa_handler);
268 }
269
270 static void
271 rl_maybe_set_sighandler (sig, handler, ohandler)
272 int sig;
273 SigHandler *handler;
274 sighandler_cxt *ohandler;
275 {
276 sighandler_cxt dummy;
277 SigHandler *oh;
278
279 sigemptyset (&dummy.sa_mask);
280 oh = rl_set_sighandler (sig, handler, ohandler);
281 if (oh == (SigHandler *)SIG_IGN)
282 rl_sigaction (sig, ohandler, &dummy);
283 }
284
285 int
286 rl_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);
295 #ifdef SIGQUIT
296 rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
297 #endif
298
299 #ifdef SIGALRM
300 oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
301 if (oh == (SigHandler *)SIG_IGN)
302 rl_sigaction (SIGALRM, &old_alrm, &dummy);
303 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
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);
310 #endif /* HAVE_POSIX_SIGNALS */
311 #endif /* SIGALRM */
312
313 #if defined (SIGTSTP)
314 rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
315 #endif /* SIGTSTP */
316
317 #if defined (SIGTTOU)
318 rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
319 #endif /* SIGTTOU */
320
321 #if defined (SIGTTIN)
322 rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
323 #endif /* SIGTTIN */
324
325 signals_set_flag = 1;
326 }
327
328 #if defined (SIGWINCH)
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 }
334 #endif /* SIGWINCH */
335
336 return 0;
337 }
338
339 int
340 rl_clear_signals ()
341 {
342 sighandler_cxt dummy;
343
344 if (rl_catch_signals && signals_set_flag == 1)
345 {
346 sigemptyset (&dummy.sa_mask);
347
348 rl_sigaction (SIGINT, &old_int, &dummy);
349 rl_sigaction (SIGTERM, &old_term, &dummy);
350 #ifdef SIGQUIT
351 rl_sigaction (SIGQUIT, &old_quit, &dummy);
352 #endif
353 #ifdef SIGALRM
354 rl_sigaction (SIGALRM, &old_alrm, &dummy);
355 #endif
356
357 #if defined (SIGTSTP)
358 rl_sigaction (SIGTSTP, &old_tstp, &dummy);
359 #endif /* SIGTSTP */
360
361 #if defined (SIGTTOU)
362 rl_sigaction (SIGTTOU, &old_ttou, &dummy);
363 #endif /* SIGTTOU */
364
365 #if defined (SIGTTIN)
366 rl_sigaction (SIGTTIN, &old_ttin, &dummy);
367 #endif /* SIGTTIN */
368
369 signals_set_flag = 0;
370 }
371
372 #if defined (SIGWINCH)
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 }
379 #endif
380
381 return 0;
382 }
383
384 /* Clean up the terminal and readline state after catching a signal, before
385 resending it to the calling application. */
386 void
387 rl_cleanup_after_signal ()
388 {
389 _rl_clean_up_for_exit ();
390 (*rl_deprep_term_function) ();
391 rl_clear_signals ();
392 rl_clear_pending_input ();
393 }
394
395 /* Reset the terminal and readline state after a signal handler returns. */
396 void
397 rl_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(). */
407 void
408 rl_free_line_state ()
409 {
410 register HIST_ENTRY *entry;
411
412 rl_free_undo_list ();
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
423 #endif /* HANDLE_SIGNALS */
This page took 0.040695 seconds and 4 git commands to generate.