Fri Sep 29 15:19:23 1995 steve chamberlain <sac@slash.cygnus.com>
Fixes for when the host WIN32, but not MSC. * complete.c: Sometimes have pwd.h * parens.c: WIN32 has similar restrictions to __GO32__. * readline.c (__GO32__): Some of this moved into rldefs.h * signals.c (__GO32__): Likewise. * rldefs.h (MSDOS||WIN32) becomes MSDOS||MSC. (WIN32&&!WIN32): New definitions.
This commit is contained in:
parent
987013cd03
commit
2e8f534a6c
3 changed files with 435 additions and 63 deletions
|
@ -1,3 +1,13 @@
|
|||
Fri Sep 29 15:19:23 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||
|
||||
Fixes for when the host WIN32, but not MSC.
|
||||
* complete.c: Sometimes have pwd.h
|
||||
* parens.c: WIN32 has similar restrictions to __GO32__.
|
||||
* readline.c (__GO32__): Some of this moved into rldefs.h
|
||||
* signals.c (__GO32__): Likewise.
|
||||
* rldefs.h (MSDOS||WIN32) becomes MSDOS||MSC.
|
||||
(WIN32&&!WIN32): New definitions.
|
||||
|
||||
Wed Sep 20 12:57:17 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* Makefile.in (maintainer-clean): New synonym for realclean.
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "sysdep.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if !defined (NO_SYS_FILE)
|
||||
# include <sys/file.h>
|
||||
|
@ -36,7 +35,7 @@ extern int errno;
|
|||
|
||||
/* These next are for filename completion. Perhaps this belongs
|
||||
in a different place. */
|
||||
#ifndef __MSDOS__
|
||||
#if !defined(__MSDOS__) && !defined(_MSC_VER)
|
||||
#include <pwd.h>
|
||||
#endif /* __MSDOS__ */
|
||||
#if defined (USG) && !defined (isc386) && !defined (sgi)
|
||||
|
@ -46,18 +45,23 @@ extern struct passwd *getpwuid (), *getpwent ();
|
|||
extern struct passwd *getpwent ();
|
||||
#endif
|
||||
|
||||
/* Included by <fcntl.h> on some systems, but not SCO, so include it here. */
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
|
||||
#if !defined (strchr)
|
||||
extern char *strchr ();
|
||||
#endif /* !strchr */
|
||||
#if !defined (strrchr)
|
||||
extern char *strrchr ();
|
||||
#endif /* !strrchr*/
|
||||
/* Possible values for do_replace in rl_complete_internal. */
|
||||
#define NO_MATCH 0
|
||||
#define SINGLE_MATCH 1
|
||||
#define MULT_MATCH 2
|
||||
|
||||
#if !defined (strchr) && !defined (__STDC__)
|
||||
extern char *strchr (), *strrchr ();
|
||||
#endif /* !strchr && !__STDC__ */
|
||||
|
||||
extern char *tilde_expand ();
|
||||
extern char *rl_copy_text ();
|
||||
|
@ -66,6 +70,10 @@ extern Function *rl_last_func;
|
|||
extern int rl_editing_mode;
|
||||
extern int screenwidth;
|
||||
|
||||
/* Forward declarations for functions defined and used in this file. */
|
||||
char *filename_completion_function ();
|
||||
char **completion_matches ();
|
||||
|
||||
static int compare_strings ();
|
||||
static char *rl_strpbrk ();
|
||||
|
||||
|
@ -86,6 +94,10 @@ int rl_complete_with_tilde_expansion = 0;
|
|||
#define VISIBLE_STATS
|
||||
|
||||
#if defined (VISIBLE_STATS)
|
||||
# if !defined (X_OK)
|
||||
# define X_OK 1
|
||||
# endif
|
||||
|
||||
static int stat_char ();
|
||||
|
||||
/* Non-zero means add an additional character to each filename displayed
|
||||
|
@ -112,7 +124,7 @@ Function *rl_completion_entry_function = (Function *)NULL;
|
|||
If this function exists and returns NULL then call the value of
|
||||
rl_completion_entry_function to try to match, otherwise use the
|
||||
array of strings returned. */
|
||||
Function *rl_attempted_completion_function = (Function *)NULL;
|
||||
CPPFunction *rl_attempted_completion_function = (CPPFunction *)NULL;
|
||||
|
||||
/* Local variable states what happened during the last completion attempt. */
|
||||
static int completion_changed_buffer = 0;
|
||||
|
@ -132,6 +144,7 @@ rl_complete (ignore, invoking_key)
|
|||
|
||||
/* List the possible completions. See description of rl_complete (). */
|
||||
rl_possible_completions (ignore, invoking_key)
|
||||
int ignore, invoking_key;
|
||||
{
|
||||
rl_complete_internal ('?');
|
||||
}
|
||||
|
@ -205,6 +218,44 @@ int rl_filename_completion_desired = 0;
|
|||
to implement FIGNORE a la SunOS csh. */
|
||||
Function *rl_ignore_some_completions_function = (Function *)NULL;
|
||||
|
||||
#if defined (SHELL)
|
||||
/* A function to strip quotes that are not protected by backquotes. It
|
||||
allows single quotes to appear within double quotes, and vice versa.
|
||||
It should be smarter. It's fairly shell-specific, hence the SHELL
|
||||
definition wrapper. */
|
||||
static char *
|
||||
_delete_quotes (text)
|
||||
char *text;
|
||||
{
|
||||
char *ret, *p, *r;
|
||||
int l, quoted;
|
||||
|
||||
l = strlen (text);
|
||||
ret = xmalloc (l + 1);
|
||||
for (quoted = 0, p = text, r = ret; p && *p; p++)
|
||||
{
|
||||
/* Allow backslash-quoted characters to pass through unscathed. */
|
||||
if (*p == '\\')
|
||||
continue;
|
||||
/* Close quote. */
|
||||
if (quoted && *p == quoted)
|
||||
{
|
||||
quoted = 0;
|
||||
continue;
|
||||
}
|
||||
/* Open quote. */
|
||||
if (quoted == 0 && (*p == '\'' || *p == '"'))
|
||||
{
|
||||
quoted = *p;
|
||||
continue;
|
||||
}
|
||||
*r++ = *p;
|
||||
}
|
||||
*r = '\0';
|
||||
return ret;
|
||||
}
|
||||
#endif /* SHELL */
|
||||
|
||||
/* Complete the word at or before point.
|
||||
WHAT_TO_DO says what to do with the completion.
|
||||
`?' means list the possible completions.
|
||||
|
@ -213,13 +264,15 @@ Function *rl_ignore_some_completions_function = (Function *)NULL;
|
|||
rl_complete_internal (what_to_do)
|
||||
int what_to_do;
|
||||
{
|
||||
char *filename_completion_function ();
|
||||
char **completion_matches (), **matches;
|
||||
char **matches;
|
||||
Function *our_func;
|
||||
int start, scan, end, delimiter = 0;
|
||||
int start, scan, end, delimiter = 0, pass_next;
|
||||
char *text, *saved_line_buffer;
|
||||
char quote_char = '\0';
|
||||
char *replacement;
|
||||
char quote_char = '\0';
|
||||
#if defined (SHELL)
|
||||
int found_quote = 0;
|
||||
#endif
|
||||
|
||||
if (rl_line_buffer)
|
||||
saved_line_buffer = savestring (rl_line_buffer);
|
||||
|
@ -229,7 +282,7 @@ rl_complete_internal (what_to_do)
|
|||
if (rl_completion_entry_function)
|
||||
our_func = rl_completion_entry_function;
|
||||
else
|
||||
our_func = (int (*)())filename_completion_function;
|
||||
our_func = (Function *)filename_completion_function;
|
||||
|
||||
/* Only the completion entry function can change this. */
|
||||
rl_filename_completion_desired = 0;
|
||||
|
@ -243,16 +296,28 @@ rl_complete_internal (what_to_do)
|
|||
{
|
||||
/* We have a list of characters which can be used in pairs to
|
||||
quote substrings for the completer. Try to find the start
|
||||
of an unclosed quoted substring.
|
||||
[FIXME: Doesn't yet handle '\' escapes to quote quotes. */
|
||||
for (scan = 0; scan < end; scan++)
|
||||
of an unclosed quoted substring. */
|
||||
/* FOUND_QUOTE is set so we know what kind of quotes we found. */
|
||||
for (scan = pass_next = 0; scan < end; scan++)
|
||||
{
|
||||
if (pass_next)
|
||||
{
|
||||
pass_next = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rl_line_buffer[scan] == '\\')
|
||||
{
|
||||
pass_next = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (quote_char != '\0')
|
||||
{
|
||||
/* Ignore everything until the matching close quote char. */
|
||||
if (rl_line_buffer[scan] == quote_char)
|
||||
{
|
||||
/* Found matching close quote. Abandon this substring. */
|
||||
/* Found matching close. Abandon this substring. */
|
||||
quote_char = '\0';
|
||||
rl_point = end;
|
||||
}
|
||||
|
@ -262,17 +327,41 @@ rl_complete_internal (what_to_do)
|
|||
/* Found start of a quoted substring. */
|
||||
quote_char = rl_line_buffer[scan];
|
||||
rl_point = scan + 1;
|
||||
#if defined (SHELL)
|
||||
if (quote_char == '\'')
|
||||
found_quote |= 1;
|
||||
else if (quote_char == '"')
|
||||
found_quote |= 2;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rl_point == end)
|
||||
{
|
||||
/* We didn't find an unclosed quoted substring upon which to do
|
||||
int quoted = 0;
|
||||
/* We didn't find an unclosed quoted substring up which to do
|
||||
completion, so use the word break characters to find the
|
||||
substring on which to do completion. */
|
||||
while (--rl_point &&
|
||||
!strchr (rl_completer_word_break_characters,
|
||||
rl_line_buffer[rl_point])) {;}
|
||||
substring on which to complete. */
|
||||
while (--rl_point)
|
||||
{
|
||||
#if defined (SHELL)
|
||||
/* Don't let word break characters in quoted substrings break
|
||||
words for the completer. */
|
||||
if (found_quote)
|
||||
{
|
||||
if (strchr (rl_completer_quote_characters, rl_line_buffer[rl_point]))
|
||||
{
|
||||
quoted = !quoted;
|
||||
continue;
|
||||
}
|
||||
if (quoted)
|
||||
continue;
|
||||
}
|
||||
#endif /* SHELL */
|
||||
if (strchr (rl_completer_word_break_characters, rl_line_buffer[rl_point]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are at a word break, then advance past it. */
|
||||
|
@ -285,13 +374,13 @@ rl_complete_internal (what_to_do)
|
|||
|
||||
/* If the character isn't needed to determine something special
|
||||
about what kind of completion to perform, then advance past it. */
|
||||
|
||||
if (!rl_special_prefixes ||
|
||||
!strchr (rl_special_prefixes, rl_line_buffer[rl_point]))
|
||||
rl_point++;
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point, we know we have an open quote if quote_char != '\0'. */
|
||||
start = rl_point;
|
||||
rl_point = end;
|
||||
text = rl_copy_text (start, end);
|
||||
|
@ -301,11 +390,11 @@ rl_complete_internal (what_to_do)
|
|||
variable rl_attempted_completion_function. */
|
||||
if (rl_attempted_completion_function)
|
||||
{
|
||||
matches =
|
||||
(char **)(*rl_attempted_completion_function) (text, start, end);
|
||||
matches = (*rl_attempted_completion_function) (text, start, end);
|
||||
|
||||
if (matches)
|
||||
{
|
||||
/* XXX - This is questionable code. - XXX */
|
||||
if (matches == (char **)-1)
|
||||
matches = (char **)NULL;
|
||||
our_func = (Function *)NULL;
|
||||
|
@ -313,6 +402,19 @@ rl_complete_internal (what_to_do)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined (SHELL)
|
||||
/* Beware -- we're stripping the quotes here. Do this only if we know
|
||||
we are doing filename completion. */
|
||||
if (found_quote && our_func == (Function *)filename_completion_function)
|
||||
{
|
||||
/* delete single and double quotes */
|
||||
replacement = _delete_quotes (text);
|
||||
free (text);
|
||||
text = replacement;
|
||||
replacement = (char *)0;
|
||||
}
|
||||
#endif /* SHELL */
|
||||
|
||||
matches = completion_matches (text, our_func);
|
||||
|
||||
after_usual_completion:
|
||||
|
@ -324,15 +426,14 @@ rl_complete_internal (what_to_do)
|
|||
{
|
||||
register int i;
|
||||
|
||||
some_matches:
|
||||
|
||||
/* It seems to me that in all the cases we handle we would like
|
||||
to ignore duplicate possibilities. Scan for the text to
|
||||
to ignore duplicate possiblilities. Scan for the text to
|
||||
insert being identical to the other completions. */
|
||||
if (rl_ignore_completion_duplicates)
|
||||
{
|
||||
char *lowest_common;
|
||||
int j, newlen = 0;
|
||||
char dead_slot;
|
||||
|
||||
/* Sort the items. */
|
||||
/* It is safe to sort this array, because the lowest common
|
||||
|
@ -348,13 +449,13 @@ rl_complete_internal (what_to_do)
|
|||
if (strcmp (matches[i], matches[i + 1]) == 0)
|
||||
{
|
||||
free (matches[i]);
|
||||
matches[i] = (char *)-1;
|
||||
matches[i] = (char *)&dead_slot;
|
||||
}
|
||||
else
|
||||
newlen++;
|
||||
}
|
||||
|
||||
/* We have marked all the dead slots with (char *)-1.
|
||||
/* We have marked all the dead slots with (char *)&dead_slot.
|
||||
Copy all the non-dead entries into a new array. */
|
||||
{
|
||||
char **temp_array =
|
||||
|
@ -362,13 +463,13 @@ rl_complete_internal (what_to_do)
|
|||
|
||||
for (i = 1, j = 1; matches[i]; i++)
|
||||
{
|
||||
if (matches[i] != (char *)-1)
|
||||
if (matches[i] != (char *)&dead_slot)
|
||||
temp_array[j++] = matches[i];
|
||||
}
|
||||
|
||||
temp_array[j] = (char *)NULL;
|
||||
|
||||
if (matches[0] != (char *)-1)
|
||||
if (matches[0] != (char *)&dead_slot)
|
||||
free (matches[0]);
|
||||
|
||||
free (matches);
|
||||
|
@ -397,7 +498,7 @@ rl_complete_internal (what_to_do)
|
|||
ignore function with the array as a parameter. It can
|
||||
munge the array, deleting matches as it desires. */
|
||||
if (rl_ignore_some_completions_function &&
|
||||
our_func == (int (*)())filename_completion_function)
|
||||
our_func == (Function *)filename_completion_function)
|
||||
(void)(*rl_ignore_some_completions_function)(matches);
|
||||
|
||||
/* If we are doing completion on quoted substrings, and any matches
|
||||
|
@ -415,34 +516,45 @@ rl_complete_internal (what_to_do)
|
|||
{
|
||||
int do_replace;
|
||||
|
||||
do_replace = 0;
|
||||
do_replace = NO_MATCH;
|
||||
|
||||
/* If there is only a single match, see if we need to
|
||||
quote it. */
|
||||
if (!matches[1] &&
|
||||
rl_strpbrk (matches[0], rl_completer_word_break_characters))
|
||||
do_replace = 1;
|
||||
/* If there is a single match, see if we need to quote it.
|
||||
This also checks whether the common prefix of several
|
||||
matches needs to be quoted. If the common prefix should
|
||||
not be checked, add !matches[1] to the if clause. */
|
||||
if (rl_strpbrk (matches[0], rl_completer_word_break_characters))
|
||||
do_replace = matches[1] ? MULT_MATCH : SINGLE_MATCH;
|
||||
|
||||
/* If there are multiple matches, check to see if any of them
|
||||
require that the substring be quoted. */
|
||||
for (i = 1; matches[i] != NULL; i++)
|
||||
if (rl_strpbrk (matches[i], rl_completer_word_break_characters))
|
||||
{
|
||||
do_replace = 1;
|
||||
break;
|
||||
}
|
||||
if (do_replace)
|
||||
if (do_replace != NO_MATCH)
|
||||
{
|
||||
#if defined (SHELL)
|
||||
/* XXX - experimental */
|
||||
/* Single-quote the replacement, since we found an
|
||||
embedded word break character in a potential match. */
|
||||
char *rtext;
|
||||
extern char *single_quote (); /* in builtins/common.c */
|
||||
/* Quote the replacement, since we found an
|
||||
embedded word break character in a potential
|
||||
match. */
|
||||
char *rtext, *mtext;
|
||||
int rlen;
|
||||
extern char *double_quote (); /* in builtins/common.c */
|
||||
|
||||
rtext = single_quote (matches[0]);
|
||||
replacement = (char *)alloca (strlen (rtext) + 1);
|
||||
/* If DO_REPLACE == MULT_MATCH, it means that there is
|
||||
more than one match. In this case, we do not add
|
||||
the closing quote or attempt to perform tilde
|
||||
expansion. If DO_REPLACE == SINGLE_MATCH, we try
|
||||
to perform tilde expansion, because double quotes
|
||||
inhibit tilde expansion by the shell. */
|
||||
|
||||
mtext = matches[0];
|
||||
if (mtext[0] == '~' && do_replace == SINGLE_MATCH)
|
||||
mtext = tilde_expand (matches[0]);
|
||||
rtext = double_quote (mtext);
|
||||
if (mtext != matches[0])
|
||||
free (mtext);
|
||||
|
||||
rlen = strlen (rtext);
|
||||
replacement = (char *)alloca (rlen + 1);
|
||||
strcpy (replacement, rtext);
|
||||
if (do_replace == MULT_MATCH)
|
||||
replacement[rlen - 1] = '\0';
|
||||
free (rtext);
|
||||
#else /* !SHELL */
|
||||
/* Found an embedded word break character in a potential
|
||||
|
@ -455,6 +567,7 @@ rl_complete_internal (what_to_do)
|
|||
#endif /* SHELL */
|
||||
}
|
||||
}
|
||||
|
||||
if (replacement)
|
||||
{
|
||||
rl_delete_text (start, rl_point);
|
||||
|
@ -541,12 +654,10 @@ rl_complete_internal (what_to_do)
|
|||
/* Handle simple case first. What if there is only one answer? */
|
||||
if (!matches[1])
|
||||
{
|
||||
char *temp;
|
||||
char *temp = (char *)NULL;
|
||||
|
||||
if (rl_filename_completion_desired)
|
||||
temp = strrchr (matches[0], '/');
|
||||
else
|
||||
temp = (char *)NULL;
|
||||
|
||||
if (!temp)
|
||||
temp = matches[0];
|
||||
|
@ -613,6 +724,7 @@ rl_complete_internal (what_to_do)
|
|||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
/* How many items of MAX length can we fit in the screen window? */
|
||||
max += 2;
|
||||
limit = screenwidth / max;
|
||||
|
@ -697,6 +809,7 @@ rl_complete_internal (what_to_do)
|
|||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "\r\nreadline: bad value for what_to_do in rl_complete\n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
@ -768,9 +881,9 @@ username_completion_function (text, state)
|
|||
int state;
|
||||
char *text;
|
||||
{
|
||||
#ifdef __GO32__
|
||||
#if defined (MINIMAL)
|
||||
return (char *)NULL;
|
||||
#else /* !__GO32__ */
|
||||
#else /* !MINIMAL */
|
||||
static char *username = (char *)NULL;
|
||||
static struct passwd *entry;
|
||||
static int namelen, first_char, first_char_loc;
|
||||
|
@ -816,9 +929,8 @@ username_completion_function (text, state)
|
|||
|
||||
return (value);
|
||||
}
|
||||
#endif /* !__GO32__ */
|
||||
#endif /* !MINIMAL */
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
|
@ -844,7 +956,7 @@ int completion_case_fold = 0;
|
|||
char **
|
||||
completion_matches (text, entry_function)
|
||||
char *text;
|
||||
char *(*entry_function) ();
|
||||
CPFunction *entry_function;
|
||||
{
|
||||
/* Number of slots in match_list. */
|
||||
int match_list_size;
|
||||
|
@ -935,6 +1047,7 @@ filename_completion_function (text, state)
|
|||
int state;
|
||||
char *text;
|
||||
{
|
||||
#ifndef WIN32
|
||||
static DIR *directory;
|
||||
static char *filename = (char *)NULL;
|
||||
static char *dirname = (char *)NULL;
|
||||
|
@ -1077,6 +1190,7 @@ filename_completion_function (text, state)
|
|||
}
|
||||
return (temp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* A function for simple tilde expansion. */
|
||||
|
|
248
readline/signals.c
Normal file
248
readline/signals.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
/* signals.c -- signal handling support for readline. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 1, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if !defined (NO_SYS_FILE)
|
||||
# include <sys/file.h>
|
||||
#endif /* !NO_SYS_FILE */
|
||||
#include <signal.h>
|
||||
|
||||
/* This is needed to include support for TIOCGWINSZ and window resizing. */
|
||||
#if defined (OSF1) || defined (BSD386) || defined (_386BSD) || defined (__BSD_4_4__) || defined (AIX)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* OSF1 || BSD386 || _386BSD || __BSD_4_4__ || AIX */
|
||||
|
||||
#include <errno.h>
|
||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
static void cr ();
|
||||
|
||||
extern int readline_echoing_p;
|
||||
extern int rl_pending_input;
|
||||
|
||||
extern int _rl_meta_flag;
|
||||
|
||||
#ifdef __STDC__
|
||||
extern void _rl_output_character_function (int);
|
||||
#else
|
||||
extern void _rl_output_character_function ();
|
||||
#endif
|
||||
|
||||
extern void free_undo_list ();
|
||||
|
||||
#if defined (VOID_SIGHANDLER)
|
||||
# define sighandler void
|
||||
#else
|
||||
# define sighandler int
|
||||
#endif /* VOID_SIGHANDLER */
|
||||
|
||||
/* This typedef is equivalant to the one for Function; it allows us
|
||||
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
|
||||
typedef sighandler SigHandler ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Signal Handling */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
static SigHandler *old_sigwinch = (SigHandler *)NULL;
|
||||
|
||||
static sighandler
|
||||
rl_handle_sigwinch (sig)
|
||||
int sig;
|
||||
{
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_set_screen_size (fileno (rl_instream), 1);
|
||||
|
||||
cr (); /* was crlf () */
|
||||
rl_forced_update_display ();
|
||||
}
|
||||
|
||||
if (old_sigwinch &&
|
||||
old_sigwinch != (SigHandler *)SIG_IGN &&
|
||||
old_sigwinch != (SigHandler *)SIG_DFL)
|
||||
(*old_sigwinch) (sig);
|
||||
#if !defined (VOID_SIGHANDLER)
|
||||
return (0);
|
||||
#endif /* VOID_SIGHANDLER */
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
|
||||
/* Interrupt handling. */
|
||||
static SigHandler
|
||||
*old_int = (SigHandler *)NULL,
|
||||
*old_tstp = (SigHandler *)NULL,
|
||||
*old_ttou = (SigHandler *)NULL,
|
||||
*old_ttin = (SigHandler *)NULL,
|
||||
*old_cont = (SigHandler *)NULL,
|
||||
*old_alrm = (SigHandler *)NULL;
|
||||
|
||||
/* Handle an interrupt character. */
|
||||
static sighandler
|
||||
rl_signal_handler (sig)
|
||||
int sig;
|
||||
{
|
||||
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
|
||||
/* Since the signal will not be blocked while we are in the signal
|
||||
handler, ignore it until rl_clear_signals resets the catcher. */
|
||||
if (sig == SIGINT)
|
||||
signal (sig, SIG_IGN);
|
||||
#endif /* !HAVE_BSD_SIGNALS */
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
{
|
||||
register HIST_ENTRY *entry;
|
||||
|
||||
free_undo_list ();
|
||||
|
||||
entry = current_history ();
|
||||
if (entry)
|
||||
entry->data = (char *)NULL;
|
||||
}
|
||||
_rl_kill_kbd_macro ();
|
||||
rl_clear_message ();
|
||||
rl_init_argument ();
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
case SIGTSTP:
|
||||
case SIGTTOU:
|
||||
case SIGTTIN:
|
||||
#endif /* SIGTSTP */
|
||||
case SIGALRM:
|
||||
rl_clean_up_for_exit ();
|
||||
rl_deprep_terminal ();
|
||||
rl_clear_signals ();
|
||||
rl_pending_input = 0;
|
||||
|
||||
kill (getpid (), sig);
|
||||
|
||||
SIGNALS_UNBLOCK;
|
||||
|
||||
rl_prep_terminal (_rl_meta_flag);
|
||||
rl_set_signals ();
|
||||
}
|
||||
|
||||
#if !defined (VOID_SIGHANDLER)
|
||||
return (0);
|
||||
#endif /* !VOID_SIGHANDLER */
|
||||
}
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
static SigHandler *
|
||||
rl_set_sighandler (sig, handler)
|
||||
int sig;
|
||||
SigHandler *handler;
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
|
||||
act.sa_handler = handler;
|
||||
act.sa_flags = 0;
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigemptyset (&oact.sa_mask);
|
||||
sigaction (sig, &act, &oact);
|
||||
return (oact.sa_handler);
|
||||
}
|
||||
|
||||
#else /* !HAVE_POSIX_SIGNALS */
|
||||
# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
rl_set_signals ()
|
||||
{
|
||||
old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
|
||||
if (old_int == (SigHandler *)SIG_IGN)
|
||||
signal (SIGINT, SIG_IGN);
|
||||
|
||||
old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
|
||||
if (old_alrm == (SigHandler *)SIG_IGN)
|
||||
signal (SIGALRM, SIG_IGN);
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
|
||||
if (old_tstp == (SigHandler *)SIG_IGN)
|
||||
signal (SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
#if defined (SIGTTOU)
|
||||
old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
|
||||
old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
|
||||
|
||||
if (old_tstp == (SigHandler *)SIG_IGN)
|
||||
{
|
||||
signal (SIGTTOU, SIG_IGN);
|
||||
signal (SIGTTIN, SIG_IGN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
old_sigwinch =
|
||||
(SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
|
||||
#endif
|
||||
}
|
||||
|
||||
rl_clear_signals ()
|
||||
{
|
||||
rl_set_sighandler (SIGINT, old_int);
|
||||
rl_set_sighandler (SIGALRM, old_alrm);
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
signal (SIGTSTP, old_tstp);
|
||||
#endif
|
||||
|
||||
#if defined (SIGTTOU)
|
||||
signal (SIGTTOU, old_ttou);
|
||||
signal (SIGTTIN, old_ttin);
|
||||
#endif
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
signal (SIGWINCH, old_sigwinch);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Move to the start of the current line. */
|
||||
static void
|
||||
cr ()
|
||||
{
|
||||
extern char *term_cr;
|
||||
|
||||
if (term_cr)
|
||||
tputs (term_cr, 1, _rl_output_character_function);
|
||||
}
|
||||
#endif /* HANDLE_SIGNALS */
|
Loading…
Reference in a new issue