1 /* signals.c -- signal handling support for readline. */
3 /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
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.
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.
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
24 #if defined (HAVE_CONFIG_H)
28 #include <stdio.h> /* Just for NULL. Yuck. */
29 #include <sys/types.h>
32 #if defined (HAVE_UNISTD_H)
34 #endif /* HAVE_UNISTD_H */
36 /* System-specific feature definitions and include files. */
39 #if defined (GWINSZ_IN_SYS_IOCTL)
40 # include <sys/ioctl.h>
41 #endif /* GWINSZ_IN_SYS_IOCTL */
43 #if defined (__GO32__)
44 # undef HANDLE_SIGNALS
47 #if defined (HANDLE_SIGNALS)
48 /* Some standard library routines. */
52 extern int readline_echoing_p
;
53 extern int rl_pending_input
;
54 extern int _rl_meta_flag
;
56 extern void free_undo_list ();
57 extern void _rl_get_screen_size ();
58 extern void _rl_redisplay_after_sigwinch ();
59 extern void _rl_clean_up_for_exit ();
60 extern void _rl_kill_kbd_macro ();
61 extern void _rl_init_argument ();
62 extern void rl_deprep_terminal (), rl_prep_terminal ();
64 #if !defined (RETSIGTYPE)
65 # if defined (VOID_SIGHANDLER)
66 # define RETSIGTYPE void
68 # define RETSIGTYPE int
69 # endif /* !VOID_SIGHANDLER */
70 #endif /* !RETSIGTYPE */
72 #if defined (VOID_SIGHANDLER)
73 # define SIGHANDLER_RETURN return
75 # define SIGHANDLER_RETURN return (0)
78 /* This typedef is equivalant to the one for Function; it allows us
79 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
80 typedef RETSIGTYPE
SigHandler ();
82 static SigHandler
*rl_set_sighandler ();
84 /* **************************************************************** */
88 /* **************************************************************** */
90 /* If we're not being compiled as part of bash, initialize handlers for
91 and catch the job control signals (SIGTTIN, SIGTTOU, SIGTSTP) and
94 # define HANDLE_JOB_SIGNALS
95 # define HANDLE_SIGTERM
98 #if defined (HAVE_POSIX_SIGNALS)
99 typedef struct sigaction sighandler_cxt
;
100 # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
102 typedef struct { SigHandler
*sa_handler
; } sighandler_cxt
;
103 # define sigemptyset(m)
104 #endif /* !HAVE_POSIX_SIGNALS */
106 static sighandler_cxt old_int
, old_alrm
;
108 #if defined (HANDLE_JOB_SIGNALS)
109 static sighandler_cxt old_tstp
, old_ttou
, old_ttin
;
110 #endif /* HANDLE_JOB_SIGNALS */
112 #if defined (HANDLE_SIGTERM)
113 static sighandler_cxt old_term
;
116 #if defined (SIGWINCH)
117 static sighandler_cxt old_winch
;
120 /* Readline signal handler functions. */
123 rl_signal_handler (sig
)
126 #if defined (HAVE_POSIX_SIGNALS)
128 #else /* !HAVE_POSIX_SIGNALS */
129 # if defined (HAVE_BSD_SIGNALS)
131 # else /* !HAVE_BSD_SIGNALS */
132 sighandler_cxt dummy_cxt
; /* needed for rl_set_sighandler call */
133 # endif /* !HAVE_BSD_SIGNALS */
134 #endif /* !HAVE_POSIX_SIGNALS */
136 #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
137 /* Since the signal will not be blocked while we are in the signal
138 handler, ignore it until rl_clear_signals resets the catcher. */
139 if (sig
== SIGINT
|| sig
== SIGALRM
)
140 rl_set_sighandler (sig
, SIG_IGN
, &dummy_cxt
);
141 #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
147 register HIST_ENTRY
*entry
;
151 entry
= current_history ();
153 entry
->data
= (char *)NULL
;
155 _rl_kill_kbd_macro ();
157 _rl_init_argument ();
159 #if defined (SIGTSTP)
166 _rl_clean_up_for_exit ();
167 (*rl_deprep_term_function
) ();
169 rl_pending_input
= 0;
171 #if defined (HAVE_POSIX_SIGNALS)
172 sigprocmask (SIG_BLOCK
, (sigset_t
*)NULL
, &set
);
173 sigdelset (&set
, sig
);
174 #else /* !HAVE_POSIX_SIGNALS */
175 # if defined (HAVE_BSD_SIGNALS)
176 omask
= sigblock (0);
177 # endif /* HAVE_BSD_SIGNALS */
178 #endif /* !HAVE_POSIX_SIGNALS */
180 kill (getpid (), sig
);
182 /* Let the signal that we just sent through. */
183 #if defined (HAVE_POSIX_SIGNALS)
184 sigprocmask (SIG_SETMASK
, &set
, (sigset_t
*)NULL
);
185 #else /* !HAVE_POSIX_SIGNALS */
186 # if defined (HAVE_BSD_SIGNALS)
187 sigsetmask (omask
& ~(sigmask (sig
)));
188 # endif /* HAVE_BSD_SIGNALS */
189 #endif /* !HAVE_POSIX_SIGNALS */
191 (*rl_prep_term_function
) (_rl_meta_flag
);
198 #if defined (SIGWINCH)
200 rl_handle_sigwinch (sig
)
205 #if defined (MUST_REINSTALL_SIGHANDLERS)
206 sighandler_cxt dummy_winch
;
208 /* We don't want to change old_winch -- it holds the state of SIGWINCH
209 disposition set by the calling application. We need this state
210 because we call the application's SIGWINCH handler after updating
211 our own idea of the screen size. */
212 rl_set_sighandler (SIGWINCH
, rl_handle_sigwinch
, &dummy_winch
);
215 if (readline_echoing_p
)
217 _rl_get_screen_size (fileno (rl_instream
), 1);
218 _rl_redisplay_after_sigwinch ();
221 /* If another sigwinch handler has been installed, call it. */
222 oh
= (SigHandler
*)old_winch
.sa_handler
;
223 if (oh
&& oh
!= (SigHandler
*)SIG_IGN
&& oh
!= (SigHandler
*)SIG_DFL
)
228 #endif /* SIGWINCH */
230 /* Functions to manage signal handling. */
232 #if !defined (HAVE_POSIX_SIGNALS)
234 rl_sigaction (sig
, nh
, oh
)
236 sighandler_cxt
*nh
, *oh
;
238 oh
->sa_handler
= signal (sig
, nh
->sa_handler
);
241 #endif /* !HAVE_POSIX_SIGNALS */
243 /* Set up a readline-specific signal handler, saving the old signal
244 information in OHANDLER. Return the old signal handler, like
247 rl_set_sighandler (sig
, handler
, ohandler
)
250 sighandler_cxt
*ohandler
;
252 #if defined (HAVE_POSIX_SIGNALS)
253 struct sigaction act
;
255 act
.sa_handler
= handler
;
257 sigemptyset (&act
.sa_mask
);
258 sigemptyset (&ohandler
->sa_mask
);
259 sigaction (sig
, &act
, ohandler
);
261 ohandler
->sa_handler
= (SigHandler
*)signal (sig
, handler
);
262 #endif /* !HAVE_POSIX_SIGNALS */
263 return (ohandler
->sa_handler
);
269 sighandler_cxt dummy
;
272 #if defined (HAVE_POSIX_SIGNALS)
273 sigemptyset (&dummy
.sa_mask
);
276 oh
= rl_set_sighandler (SIGINT
, rl_signal_handler
, &old_int
);
277 if (oh
== (SigHandler
*)SIG_IGN
)
278 rl_sigaction (SIGINT
, &old_int
, &dummy
);
280 oh
= rl_set_sighandler (SIGALRM
, rl_signal_handler
, &old_alrm
);
281 if (oh
== (SigHandler
*)SIG_IGN
)
282 rl_sigaction (SIGALRM
, &old_alrm
, &dummy
);
283 #if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
284 /* If the application using readline has already installed a signal
285 handler with SA_RESTART, SIGALRM will cause reads to be restarted
286 automatically, so readline should just get out of the way. Since
287 we tested for SIG_IGN above, we can just test for SIG_DFL here. */
288 if (oh
!= (SigHandler
*)SIG_DFL
&& (old_alrm
.sa_flags
& SA_RESTART
))
289 rl_sigaction (SIGALRM
, &old_alrm
, &dummy
);
290 #endif /* HAVE_POSIX_SIGNALS */
292 #if defined (HANDLE_JOB_SIGNALS)
294 #if defined (SIGTSTP)
295 oh
= rl_set_sighandler (SIGTSTP
, rl_signal_handler
, &old_tstp
);
296 if (oh
== (SigHandler
*)SIG_IGN
)
297 rl_sigaction (SIGTSTP
, &old_tstp
, &dummy
);
299 oh
= (SigHandler
*)NULL
;
302 #if defined (SIGTTOU)
303 rl_set_sighandler (SIGTTOU
, rl_signal_handler
, &old_ttou
);
304 rl_set_sighandler (SIGTTIN
, rl_signal_handler
, &old_ttin
);
306 if (oh
== (SigHandler
*)SIG_IGN
)
308 rl_set_sighandler (SIGTTOU
, SIG_IGN
, &dummy
);
309 rl_set_sighandler (SIGTTIN
, SIG_IGN
, &dummy
);
313 #endif /* HANDLE_JOB_SIGNALS */
315 #if defined (HANDLE_SIGTERM)
316 /* Handle SIGTERM if we're not being compiled as part of bash. */
317 rl_set_sighandler (SIGTERM
, rl_signal_handler
, &old_term
);
318 #endif /* HANDLE_SIGTERM */
320 #if defined (SIGWINCH)
321 rl_set_sighandler (SIGWINCH
, rl_handle_sigwinch
, &old_winch
);
322 #endif /* SIGWINCH */
330 sighandler_cxt dummy
;
332 #if defined (HAVE_POSIX_SIGNALS)
333 sigemptyset (&dummy
.sa_mask
);
336 rl_sigaction (SIGINT
, &old_int
, &dummy
);
337 rl_sigaction (SIGALRM
, &old_alrm
, &dummy
);
339 #if defined (HANDLE_JOB_SIGNALS)
341 #if defined (SIGTSTP)
342 rl_sigaction (SIGTSTP
, &old_tstp
, &dummy
);
345 #if defined (SIGTTOU)
346 rl_sigaction (SIGTTOU
, &old_ttou
, &dummy
);
347 rl_sigaction (SIGTTIN
, &old_ttin
, &dummy
);
350 #endif /* HANDLE_JOB_SIGNALS */
352 #if defined (HANDLE_SIGTERM)
353 rl_sigaction (SIGTERM
, &old_term
, &dummy
);
354 #endif /* HANDLE_SIGTERM */
356 #if defined (SIGWINCH)
357 sigemptyset (&dummy
.sa_mask
);
358 rl_sigaction (SIGWINCH
, &old_winch
, &dummy
);
363 #endif /* HANDLE_SIGNALS */