OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [readline/] [signals.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* 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
#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 (__GO32__) && !defined(__DJGPP__)
44
#  undef HANDLE_SIGNALS
45
#endif /* __GO32__  && !__DJGPP__ */
46
 
47
#if defined (HANDLE_SIGNALS)
48
/* Some standard library routines. */
49
#include "readline.h"
50
#include "history.h"
51
 
52
#if !defined (RETSIGTYPE)
53
#  if defined (VOID_SIGHANDLER)
54
#    define RETSIGTYPE void
55
#  else
56
#    define RETSIGTYPE int
57
#  endif /* !VOID_SIGHANDLER */
58
#endif /* !RETSIGTYPE */
59
 
60
#if defined (VOID_SIGHANDLER)
61
#  define SIGHANDLER_RETURN return
62
#else
63
#  define SIGHANDLER_RETURN return (0)
64
#endif
65
 
66
/* This typedef is equivalant to the one for Function; it allows us
67
   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
68
typedef RETSIGTYPE SigHandler ();
69
 
70
extern int readline_echoing_p;
71
extern int rl_pending_input;
72
extern int _rl_meta_flag;
73
 
74
extern void free_undo_list ();
75
extern void _rl_get_screen_size ();
76
extern void _rl_redisplay_after_sigwinch ();
77
extern void _rl_clean_up_for_exit ();
78
extern void _rl_kill_kbd_macro ();
79
extern void _rl_init_argument ();
80
extern void rl_deprep_terminal (), rl_prep_terminal ();
81
 
82
static SigHandler *rl_set_sighandler ();
83
 
84
/* Exported variables for use by applications. */
85
 
86
/* If non-zero, readline will install its own signal handlers for
87
   SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
88
int rl_catch_signals = 1;
89
 
90
/* If non-zero, readline will install a signal handler for SIGWINCH. */
91
#ifdef SIGWINCH
92
int rl_catch_sigwinch = 1;
93
#endif
94
 
95
static int signals_set_flag;
96
#ifdef SIGWINCH
97
static int sigwinch_set_flag;
98
#endif
99
 
100
/* **************************************************************** */
101
/*                                                                  */
102
/*                         Signal Handling                          */
103
/*                                                                  */
104
/* **************************************************************** */
105
 
106
#if defined (HAVE_POSIX_SIGNALS)
107
typedef struct sigaction sighandler_cxt;
108
#  define rl_sigaction(s, nh, oh)       sigaction(s, nh, oh)
109
#else
110
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
111
#  define sigemptyset(m)
112
#endif /* !HAVE_POSIX_SIGNALS */
113
 
114
static sighandler_cxt old_int, old_term, old_alrm, old_quit;
115
#if defined (SIGTSTP)
116
static sighandler_cxt old_tstp, old_ttou, old_ttin;
117
#endif
118
#if defined (SIGWINCH)
119
static sighandler_cxt old_winch;
120
#endif
121
 
122
/* Readline signal handler functions. */
123
 
124
static RETSIGTYPE
125
rl_signal_handler (sig)
126
     int sig;
127
{
128
#if defined (HAVE_POSIX_SIGNALS)
129
  sigset_t set;
130
#else /* !HAVE_POSIX_SIGNALS */
131
#  if defined (HAVE_BSD_SIGNALS)
132
  long omask;
133
#  else /* !HAVE_BSD_SIGNALS */
134
  sighandler_cxt dummy_cxt;     /* needed for rl_set_sighandler call */
135
#  endif /* !HAVE_BSD_SIGNALS */
136
#endif /* !HAVE_POSIX_SIGNALS */
137
 
138
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
139
  /* Since the signal will not be blocked while we are in the signal
140
     handler, ignore it until rl_clear_signals resets the catcher. */
141
  if (sig == SIGINT || sig == SIGALRM)
142
    rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
143
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
144
 
145
  switch (sig)
146
    {
147
    case SIGINT:
148
      rl_free_line_state ();
149
      /* FALLTHROUGH */
150
 
151
#if defined (SIGTSTP)
152
    case SIGTSTP:
153
    case SIGTTOU:
154
    case SIGTTIN:
155
#endif /* SIGTSTP */
156
    case SIGALRM:
157
    case SIGTERM:
158
    case SIGQUIT:
159
      rl_cleanup_after_signal ();
160
 
161
#if defined (HAVE_POSIX_SIGNALS)
162
      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
163
      sigdelset (&set, sig);
164
#else /* !HAVE_POSIX_SIGNALS */
165
#  if defined (HAVE_BSD_SIGNALS)
166
      omask = sigblock (0);
167
#  endif /* HAVE_BSD_SIGNALS */
168
#endif /* !HAVE_POSIX_SIGNALS */
169
 
170
      kill (getpid (), sig);
171
 
172
      /* Let the signal that we just sent through.  */
173
#if defined (HAVE_POSIX_SIGNALS)
174
      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
175
#else /* !HAVE_POSIX_SIGNALS */
176
#  if defined (HAVE_BSD_SIGNALS)
177
      sigsetmask (omask & ~(sigmask (sig)));
178
#  endif /* HAVE_BSD_SIGNALS */
179
#endif /* !HAVE_POSIX_SIGNALS */
180
 
181
      rl_reset_after_signal ();
182
    }
183
 
184
  SIGHANDLER_RETURN;
185
}
186
 
187
#if defined (SIGWINCH)
188
static RETSIGTYPE
189
rl_sigwinch_handler (sig)
190
     int sig;
191
{
192
  SigHandler *oh;
193
 
194
#if defined (MUST_REINSTALL_SIGHANDLERS)
195
  sighandler_cxt dummy_winch;
196
 
197
  /* We don't want to change old_winch -- it holds the state of SIGWINCH
198
     disposition set by the calling application.  We need this state
199
     because we call the application's SIGWINCH handler after updating
200
     our own idea of the screen size. */
201
  rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
202
#endif
203
 
204
  rl_resize_terminal ();
205
 
206
  /* If another sigwinch handler has been installed, call it. */
207
  oh = (SigHandler *)old_winch.sa_handler;
208
  if (oh &&  oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
209
    (*oh) (sig);
210
 
211
  SIGHANDLER_RETURN;
212
}
213
#endif  /* SIGWINCH */
214
 
215
/* Functions to manage signal handling. */
216
 
217
#if !defined (HAVE_POSIX_SIGNALS)
218
static int
219
rl_sigaction (sig, nh, oh)
220
     int sig;
221
     sighandler_cxt *nh, *oh;
222
{
223
  oh->sa_handler = signal (sig, nh->sa_handler);
224
  return 0;
225
}
226
#endif /* !HAVE_POSIX_SIGNALS */
227
 
228
/* Set up a readline-specific signal handler, saving the old signal
229
   information in OHANDLER.  Return the old signal handler, like
230
   signal(). */
231
static SigHandler *
232
rl_set_sighandler (sig, handler, ohandler)
233
     int sig;
234
     SigHandler *handler;
235
     sighandler_cxt *ohandler;
236
{
237
#if defined (HAVE_POSIX_SIGNALS)
238
  struct sigaction act;
239
 
240
  act.sa_handler = handler;
241
  act.sa_flags = 0;
242
  sigemptyset (&act.sa_mask);
243
  sigemptyset (&ohandler->sa_mask);
244
  sigaction (sig, &act, ohandler);
245
#else
246
  ohandler->sa_handler = (SigHandler *)signal (sig, handler);
247
#endif /* !HAVE_POSIX_SIGNALS */
248
  return (ohandler->sa_handler);
249
}
250
 
251
static void
252
rl_maybe_set_sighandler (sig, handler, ohandler)
253
     int sig;
254
     SigHandler *handler;
255
     sighandler_cxt *ohandler;
256
{
257
  sighandler_cxt dummy;
258
  SigHandler *oh;
259
 
260
  sigemptyset (&dummy.sa_mask);
261
  oh = rl_set_sighandler (sig, handler, ohandler);
262
  if (oh == (SigHandler *)SIG_IGN)
263
    rl_sigaction (sig, ohandler, &dummy);
264
}
265
 
266
int
267
rl_set_signals ()
268
{
269
  sighandler_cxt dummy;
270
  SigHandler *oh;
271
 
272
  if (rl_catch_signals && signals_set_flag == 0)
273
    {
274
      rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
275
      rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
276
      rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
277
 
278
      oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
279
      if (oh == (SigHandler *)SIG_IGN)
280
        rl_sigaction (SIGALRM, &old_alrm, &dummy);
281
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
282
      /* If the application using readline has already installed a signal
283
         handler with SA_RESTART, SIGALRM will cause reads to be restarted
284
         automatically, so readline should just get out of the way.  Since
285
         we tested for SIG_IGN above, we can just test for SIG_DFL here. */
286
      if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
287
        rl_sigaction (SIGALRM, &old_alrm, &dummy);
288
#endif /* HAVE_POSIX_SIGNALS */
289
 
290
#if defined (SIGTSTP)
291
      rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
292
#endif /* SIGTSTP */
293
 
294
#if defined (SIGTTOU)
295
      rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
296
#endif /* SIGTTOU */
297
 
298
#if defined (SIGTTIN)
299
      rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
300
#endif /* SIGTTIN */
301
 
302
      signals_set_flag = 1;
303
    }
304
 
305
#if defined (SIGWINCH)
306
  if (rl_catch_sigwinch && sigwinch_set_flag == 0)
307
    {
308
      rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
309
      sigwinch_set_flag = 1;
310
    }
311
#endif /* SIGWINCH */
312
 
313
  return 0;
314
}
315
 
316
int
317
rl_clear_signals ()
318
{
319
  sighandler_cxt dummy;
320
 
321
  if (rl_catch_signals && signals_set_flag == 1)
322
    {
323
      sigemptyset (&dummy.sa_mask);
324
 
325
      rl_sigaction (SIGINT, &old_int, &dummy);
326
      rl_sigaction (SIGTERM, &old_term, &dummy);
327
      rl_sigaction (SIGQUIT, &old_quit, &dummy);
328
      rl_sigaction (SIGALRM, &old_alrm, &dummy);
329
 
330
#if defined (SIGTSTP)
331
      rl_sigaction (SIGTSTP, &old_tstp, &dummy);
332
#endif /* SIGTSTP */
333
 
334
#if defined (SIGTTOU)
335
      rl_sigaction (SIGTTOU, &old_ttou, &dummy);
336
#endif /* SIGTTOU */
337
 
338
#if defined (SIGTTIN)
339
      rl_sigaction (SIGTTIN, &old_ttin, &dummy);
340
#endif /* SIGTTIN */
341
 
342
      signals_set_flag = 0;
343
    }
344
 
345
#if defined (SIGWINCH)
346
  if (rl_catch_sigwinch && sigwinch_set_flag == 1)
347
    {
348
      sigemptyset (&dummy.sa_mask);
349
      rl_sigaction (SIGWINCH, &old_winch, &dummy);
350
      sigwinch_set_flag = 0;
351
    }
352
#endif
353
 
354
  return 0;
355
}
356
 
357
/* Clean up the terminal and readline state after catching a signal, before
358
   resending it to the calling application. */
359
void
360
rl_cleanup_after_signal ()
361
{
362
  _rl_clean_up_for_exit ();
363
  (*rl_deprep_term_function) ();
364
  rl_clear_signals ();
365
  rl_pending_input = 0;
366
}
367
 
368
/* Reset the terminal and readline state after a signal handler returns. */
369
void
370
rl_reset_after_signal ()
371
{
372
  (*rl_prep_term_function) (_rl_meta_flag);
373
  rl_set_signals ();
374
}
375
 
376
/* Free up the readline variable line state for the current line (undo list,
377
   any partial history entry, any keyboard macros in progress, and any
378
   numeric arguments in process) after catching a signal, before calling
379
   rl_cleanup_after_signal(). */
380
void
381
rl_free_line_state ()
382
{
383
  register HIST_ENTRY *entry;
384
 
385
  free_undo_list ();
386
 
387
  entry = current_history ();
388
  if (entry)
389
    entry->data = (char *)NULL;
390
 
391
  _rl_kill_kbd_macro ();
392
  rl_clear_message ();
393
  _rl_init_argument ();
394
}
395
 
396
#endif  /* HANDLE_SIGNALS */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.