OSDN Git Service

* configure.in: Remove --enable-shared option. It shouldn't be used for gdb.
[pf3gnuchains/sourceware.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 */