Imported from ../bash-1.14.7.tar.gz.
[platform/upstream/bash.git] / lib / 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 1, 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    675 Mass Ave, Cambridge, MA 02139, USA. */
22 #define READLINE_LIBRARY
23
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <fcntl.h>
27 #if !defined (NO_SYS_FILE)
28 #  include <sys/file.h>
29 #endif /* !NO_SYS_FILE */
30 #include <signal.h>
31
32 #if defined (HAVE_UNISTD_H)
33 #  include <unistd.h>
34 #endif /* HAVE_UNISTD_H */
35
36 #if defined (HAVE_STDLIB_H)
37 #  include <stdlib.h>
38 #else
39 #  include "ansi_stdlib.h"
40 #endif /* HAVE_STDLIB_H */
41
42 #include <errno.h>
43 /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
44 #if !defined (errno)
45 extern int errno;
46 #endif /* !errno */
47
48 #include "posixstat.h"
49
50 /* System-specific feature definitions and include files. */
51 #include "rldefs.h"
52
53 #if defined (GWINSZ_IN_SYS_IOCTL)
54 #  include <sys/ioctl.h>
55 #endif /* GWINSZ_IN_SYS_IOCTL */
56
57 /* Some standard library routines. */
58 #include "readline.h"
59 #include "history.h"
60
61 extern int readline_echoing_p;
62 extern int rl_pending_input;
63 extern int _rl_meta_flag;
64
65 extern void free_undo_list ();
66
67 #if defined (VOID_SIGHANDLER)
68 #  define sighandler void
69 #else
70 #  define sighandler int
71 #endif /* VOID_SIGHANDLER */
72
73 /* This typedef is equivalant to the one for Function; it allows us
74    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
75 typedef sighandler SigHandler ();
76
77 #if defined (__GO32__)
78 #  undef HANDLE_SIGNALS
79 #endif /* __GO32__ */
80
81 #if defined (STATIC_MALLOC)
82 static char *xmalloc (), *xrealloc ();
83 #else
84 extern char *xmalloc (), *xrealloc ();
85 #endif /* STATIC_MALLOC */
86
87 \f
88 /* **************************************************************** */
89 /*                                                                  */
90 /*                         Signal Handling                          */
91 /*                                                                  */
92 /* **************************************************************** */
93
94 #if defined (SIGWINCH)
95 static SigHandler *old_sigwinch = (SigHandler *)NULL;
96
97 static sighandler
98 rl_handle_sigwinch (sig)
99      int sig;
100 {
101   if (readline_echoing_p)
102     {
103       _rl_set_screen_size (fileno (rl_instream), 1);
104       _rl_redisplay_after_sigwinch ();
105     }
106
107   if (old_sigwinch &&
108       old_sigwinch != (SigHandler *)SIG_IGN &&
109       old_sigwinch != (SigHandler *)SIG_DFL)
110     (*old_sigwinch) (sig);
111 #if !defined (VOID_SIGHANDLER)
112   return (0);
113 #endif /* VOID_SIGHANDLER */
114 }
115 #endif  /* SIGWINCH */
116
117 #if defined (HANDLE_SIGNALS)
118 /* Interrupt handling. */
119 static SigHandler
120   *old_int  = (SigHandler *)NULL,
121   *old_alrm = (SigHandler *)NULL;
122 #if !defined (SHELL)
123 static SigHandler
124   *old_tstp = (SigHandler *)NULL,
125   *old_ttou = (SigHandler *)NULL,
126   *old_ttin = (SigHandler *)NULL,
127   *old_cont = (SigHandler *)NULL;
128 #endif /* !SHELL */
129
130 /* Handle an interrupt character. */
131 static sighandler
132 rl_signal_handler (sig)
133      int sig;
134 {
135 #if defined (HAVE_POSIX_SIGNALS)
136   sigset_t set;
137 #else /* !HAVE_POSIX_SIGNALS */
138 #  if defined (HAVE_BSD_SIGNALS)
139   long omask;
140 #  endif /* HAVE_BSD_SIGNALS */
141 #endif /* !HAVE_POSIX_SIGNALS */
142
143 #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
144   /* Since the signal will not be blocked while we are in the signal
145      handler, ignore it until rl_clear_signals resets the catcher. */
146   if (sig == SIGINT)
147     signal (sig, SIG_IGN);
148 #endif /* !HAVE_BSD_SIGNALS */
149
150   switch (sig)
151     {
152     case SIGINT:
153       {
154         register HIST_ENTRY *entry;
155
156         free_undo_list ();
157
158         entry = current_history ();
159         if (entry)
160           entry->data = (char *)NULL;
161       }
162       _rl_kill_kbd_macro ();
163       rl_clear_message ();
164       rl_init_argument ();
165
166 #if defined (SIGTSTP)
167     case SIGTSTP:
168     case SIGTTOU:
169     case SIGTTIN:
170 #endif /* SIGTSTP */
171     case SIGALRM:
172       rl_clean_up_for_exit ();
173       rl_deprep_terminal ();
174       rl_clear_signals ();
175       rl_pending_input = 0;
176
177 #if defined (HAVE_POSIX_SIGNALS)
178       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
179       sigdelset (&set, sig);
180 #else /* !HAVE_POSIX_SIGNALS */
181 #  if defined (HAVE_BSD_SIGNALS)
182       omask = sigblock (0);
183 #  endif /* HAVE_BSD_SIGNALS */
184 #endif /* !HAVE_POSIX_SIGNALS */
185
186       kill (getpid (), sig);
187
188       /* Let the signal that we just sent through.  */
189 #if defined (HAVE_POSIX_SIGNALS)
190       sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
191 #else /* !HAVE_POSIX_SIGNALS */
192 #  if defined (HAVE_BSD_SIGNALS)
193       sigsetmask (omask & ~(sigmask (sig)));
194 #  endif /* HAVE_BSD_SIGNALS */
195 #endif /* !HAVE_POSIX_SIGNALS */
196
197       rl_prep_terminal (_rl_meta_flag);
198       rl_set_signals ();
199     }
200
201 #if !defined (VOID_SIGHANDLER)
202   return (0);
203 #endif /* !VOID_SIGHANDLER */
204 }
205
206 #if defined (HAVE_POSIX_SIGNALS)
207 static SigHandler *
208 rl_set_sighandler (sig, handler)
209      int sig;
210      SigHandler *handler;
211 {
212   struct sigaction act, oact;
213
214   act.sa_handler = handler;
215   act.sa_flags = 0;
216   sigemptyset (&act.sa_mask);
217   sigemptyset (&oact.sa_mask);
218   sigaction (sig, &act, &oact);
219   return (oact.sa_handler);
220 }
221
222 #else /* !HAVE_POSIX_SIGNALS */
223 #  define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
224 #endif /* !HAVE_POSIX_SIGNALS */
225
226 rl_set_signals ()
227 {
228   old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
229   if (old_int == (SigHandler *)SIG_IGN)
230     rl_set_sighandler (SIGINT, SIG_IGN);
231
232   old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
233   if (old_alrm == (SigHandler *)SIG_IGN)
234     rl_set_sighandler (SIGALRM, SIG_IGN);
235
236 #if !defined (SHELL)
237
238 #if defined (SIGTSTP)
239   old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
240   if (old_tstp == (SigHandler *)SIG_IGN)
241     rl_set_sighandler (SIGTSTP, SIG_IGN);
242 #endif /* SIGTSTP */
243 #if defined (SIGTTOU)
244   old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
245   old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
246
247   if (old_tstp == (SigHandler *)SIG_IGN)
248     {
249       rl_set_sighandler (SIGTTOU, SIG_IGN);
250       rl_set_sighandler (SIGTTIN, SIG_IGN);
251     }
252 #endif /* SIGTTOU */
253
254 #endif /* !SHELL */
255
256 #if defined (SIGWINCH)
257   old_sigwinch =
258     (SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
259 #endif /* SIGWINCH */
260   return 0;
261 }
262
263 rl_clear_signals ()
264 {
265   rl_set_sighandler (SIGINT, old_int);
266   rl_set_sighandler (SIGALRM, old_alrm);
267
268 #if !defined (SHELL)
269
270 #if defined (SIGTSTP)
271   rl_set_sighandler (SIGTSTP, old_tstp);
272 #endif
273
274 #if defined (SIGTTOU)
275   rl_set_sighandler (SIGTTOU, old_ttou);
276   rl_set_sighandler (SIGTTIN, old_ttin);
277 #endif /* SIGTTOU */
278
279 #endif /* !SHELL */
280
281 #if defined (SIGWINCH)
282   rl_set_sighandler (SIGWINCH, old_sigwinch);
283 #endif
284
285   return 0;
286 }
287 #endif  /* HANDLE_SIGNALS */