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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [readline/] [signals.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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