* ld.texinfo (Simple Example): Rewrite a few things as suggested
[deliverable/binutils-gdb.git] / readline / signals.c
CommitLineData
2e8f534a
SC
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
23#include <stdio.h>
24#include <sys/types.h>
25#include <fcntl.h>
26#if !defined (NO_SYS_FILE)
27# include <sys/file.h>
28#endif /* !NO_SYS_FILE */
29#include <signal.h>
30
31/* This is needed to include support for TIOCGWINSZ and window resizing. */
32#if defined (OSF1) || defined (BSD386) || defined (_386BSD) || defined (__BSD_4_4__) || defined (AIX)
33# include <sys/ioctl.h>
34#endif /* OSF1 || BSD386 || _386BSD || __BSD_4_4__ || AIX */
35
36#include <errno.h>
37/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
38#if !defined (errno)
39extern int errno;
40#endif /* !errno */
41
42/* System-specific feature definitions and include files. */
43#include "rldefs.h"
44
45/* Some standard library routines. */
46#include "readline.h"
47#include "history.h"
48
49static void cr ();
50
51extern int readline_echoing_p;
52extern int rl_pending_input;
53
54extern int _rl_meta_flag;
55
56#ifdef __STDC__
57extern void _rl_output_character_function (int);
58#else
59extern void _rl_output_character_function ();
60#endif
61
62extern void free_undo_list ();
63
64#if defined (VOID_SIGHANDLER)
65# define sighandler void
66#else
67# define sighandler int
68#endif /* VOID_SIGHANDLER */
69
70/* This typedef is equivalant to the one for Function; it allows us
71 to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
72typedef sighandler SigHandler ();
73
74/* **************************************************************** */
75/* */
76/* Signal Handling */
77/* */
78/* **************************************************************** */
79
80#if defined (HANDLE_SIGNALS)
81
82#if defined (SIGWINCH)
83static SigHandler *old_sigwinch = (SigHandler *)NULL;
84
85static sighandler
86rl_handle_sigwinch (sig)
87 int sig;
88{
89 if (readline_echoing_p)
90 {
91 _rl_set_screen_size (fileno (rl_instream), 1);
92
93 cr (); /* was crlf () */
94 rl_forced_update_display ();
95 }
96
97 if (old_sigwinch &&
98 old_sigwinch != (SigHandler *)SIG_IGN &&
99 old_sigwinch != (SigHandler *)SIG_DFL)
100 (*old_sigwinch) (sig);
101#if !defined (VOID_SIGHANDLER)
102 return (0);
103#endif /* VOID_SIGHANDLER */
104}
105#endif /* SIGWINCH */
106
107/* Interrupt handling. */
108static SigHandler
109 *old_int = (SigHandler *)NULL,
110 *old_tstp = (SigHandler *)NULL,
111 *old_ttou = (SigHandler *)NULL,
112 *old_ttin = (SigHandler *)NULL,
113 *old_cont = (SigHandler *)NULL,
114 *old_alrm = (SigHandler *)NULL;
115
116/* Handle an interrupt character. */
117static sighandler
118rl_signal_handler (sig)
119 int sig;
120{
121#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
122 /* Since the signal will not be blocked while we are in the signal
123 handler, ignore it until rl_clear_signals resets the catcher. */
124 if (sig == SIGINT)
125 signal (sig, SIG_IGN);
126#endif /* !HAVE_BSD_SIGNALS */
127
128 switch (sig)
129 {
130 case SIGINT:
131 {
132 register HIST_ENTRY *entry;
133
134 free_undo_list ();
135
136 entry = current_history ();
137 if (entry)
138 entry->data = (char *)NULL;
139 }
140 _rl_kill_kbd_macro ();
141 rl_clear_message ();
142 rl_init_argument ();
143
144#if defined (SIGTSTP)
145 case SIGTSTP:
146 case SIGTTOU:
147 case SIGTTIN:
148#endif /* SIGTSTP */
149 case SIGALRM:
150 rl_clean_up_for_exit ();
151 rl_deprep_terminal ();
152 rl_clear_signals ();
153 rl_pending_input = 0;
154
155 kill (getpid (), sig);
156
157 SIGNALS_UNBLOCK;
158
159 rl_prep_terminal (_rl_meta_flag);
160 rl_set_signals ();
161 }
162
163#if !defined (VOID_SIGHANDLER)
164 return (0);
165#endif /* !VOID_SIGHANDLER */
166}
167
168#if defined (HAVE_POSIX_SIGNALS)
169static SigHandler *
170rl_set_sighandler (sig, handler)
171 int sig;
172 SigHandler *handler;
173{
174 struct sigaction act, oact;
175
176 act.sa_handler = handler;
177 act.sa_flags = 0;
178 sigemptyset (&act.sa_mask);
179 sigemptyset (&oact.sa_mask);
180 sigaction (sig, &act, &oact);
181 return (oact.sa_handler);
182}
183
184#else /* !HAVE_POSIX_SIGNALS */
185# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
186#endif /* !HAVE_POSIX_SIGNALS */
187
188rl_set_signals ()
189{
190 old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
191 if (old_int == (SigHandler *)SIG_IGN)
192 signal (SIGINT, SIG_IGN);
193
194 old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
195 if (old_alrm == (SigHandler *)SIG_IGN)
196 signal (SIGALRM, SIG_IGN);
197
198#if defined (SIGTSTP)
199 old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
200 if (old_tstp == (SigHandler *)SIG_IGN)
201 signal (SIGTSTP, SIG_IGN);
202#endif
203#if defined (SIGTTOU)
204 old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
205 old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
206
207 if (old_tstp == (SigHandler *)SIG_IGN)
208 {
209 signal (SIGTTOU, SIG_IGN);
210 signal (SIGTTIN, SIG_IGN);
211 }
212#endif
213
214#if defined (SIGWINCH)
215 old_sigwinch =
216 (SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
217#endif
218}
219
220rl_clear_signals ()
221{
222 rl_set_sighandler (SIGINT, old_int);
223 rl_set_sighandler (SIGALRM, old_alrm);
224
225#if defined (SIGTSTP)
226 signal (SIGTSTP, old_tstp);
227#endif
228
229#if defined (SIGTTOU)
230 signal (SIGTTOU, old_ttou);
231 signal (SIGTTIN, old_ttin);
232#endif
233
234#if defined (SIGWINCH)
235 signal (SIGWINCH, old_sigwinch);
236#endif
237}
238
239/* Move to the start of the current line. */
240static void
241cr ()
242{
243 extern char *term_cr;
244
245 if (term_cr)
246 tputs (term_cr, 1, _rl_output_character_function);
247}
248#endif /* HANDLE_SIGNALS */
This page took 0.130733 seconds and 4 git commands to generate.