Imported from ../bash-2.05b.tar.gz.

This commit is contained in:
Jari Aalto 2002-07-17 14:10:11 +00:00
commit 7117c2d221
362 changed files with 34387 additions and 15063 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -36,9 +36,7 @@
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# if defined (PREFER_VARARGS)
# include <varargs.h>
# endif
# include <varargs.h>
#endif
#include "../bashansi.h"
@ -64,8 +62,7 @@
extern int errno;
#endif /* !errno */
extern int no_symbolic_links;
extern int indirection_level, startup_state, subshell_environment;
extern int indirection_level, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int running_trap;
@ -86,7 +83,6 @@ sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
/* This is a lot like report_error (), but it is for shell builtins
instead of shell control structures, and it won't ever exit the
shell. */
#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
builtin_error (const char *format, ...)
@ -102,32 +98,18 @@ builtin_error (format, va_alist)
name = get_name_for_error ();
fprintf (stderr, "%s: ", name);
if (interactive_shell == 0)
fprintf (stderr, "line %d: ", executing_line_number ());
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
#endif
SH_VA_START (args, format);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
#else /* !USE_VARARGS */
void
builtin_error (format, arg1, arg2, arg3, arg4, arg5)
char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
{
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
fprintf (stderr, "\n");
fflush (stderr);
}
#endif /* !USE_VARARGS */
/* Print a usage summary for the currently-executing builtin command. */
void
@ -152,15 +134,6 @@ no_args (list)
}
}
/* Function called when one of the builtin commands detects a bad
option. */
void
bad_option (s)
char *s;
{
builtin_error ("unknown option: %s", s);
}
/* Check that no options were given to the currently-executing builtin,
and return 0 if there were options. */
int
@ -176,6 +149,119 @@ no_options (list)
return (0);
}
void
sh_needarg (s)
char *s;
{
builtin_error ("%s: option requires an argument", s);
}
void
sh_neednumarg (s)
char *s;
{
builtin_error ("%s: numeric argument required", s);
}
void
sh_notfound (s)
char *s;
{
builtin_error ("%s: not found", s);
}
/* Function called when one of the builtin commands detects an invalid
option. */
void
sh_invalidopt (s)
char *s;
{
builtin_error ("%s: invalid option", s);
}
void
sh_invalidoptname (s)
char *s;
{
builtin_error ("%s: invalid option name", s);
}
void
sh_invalidid (s)
char *s;
{
builtin_error ("`%s': not a valid identifier", s);
}
void
sh_invalidnum (s)
char *s;
{
builtin_error ("%s: invalid number", s);
}
void
sh_invalidsig (s)
char *s;
{
builtin_error ("%s: invalid signal specification", s);
}
void
sh_badpid (s)
char *s;
{
builtin_error ("`%s': not a pid or valid job spec", s);
}
void
sh_readonly (s)
const char *s;
{
builtin_error ("%s: readonly variable", s);
}
void
sh_erange (s, desc)
char *s, *desc;
{
if (s)
builtin_error ("%s: %s out of range", s, desc ? desc : "argument");
else
builtin_error ("%s out of range", desc ? desc : "argument");
}
#if defined (JOB_CONTROL)
void
sh_badjob (s)
char *s;
{
builtin_error ("%s: no such job", s);
}
void
sh_nojobs (s)
char *s;
{
if (s)
builtin_error ("%s: no job control");
else
builtin_error ("no job control");
}
#endif
#if defined (RESTRICTED_SHELL)
void
sh_restricted (s)
char *s;
{
if (s)
builtin_error ("%s: restricted", s);
else
builtin_error ("restricted");
}
#endif
/* **************************************************************** */
/* */
/* Shell positional parameter manipulation */
@ -192,7 +278,7 @@ make_builtin_argv (list, ip)
{
char **argv;
argv = word_list_to_argv (list, 0, 1, ip);
argv = strvec_from_word_list (list, 0, 1, ip);
argv[0] = this_command_name;
return argv;
}
@ -235,67 +321,6 @@ remember_args (list, destructive)
set_dollar_vars_changed ();
}
/* **************************************************************** */
/* */
/* Pushing and Popping variable contexts */
/* */
/* **************************************************************** */
static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
static int dollar_arg_stack_slots;
static int dollar_arg_stack_index;
void
push_context ()
{
push_dollar_vars ();
variable_context++;
}
void
pop_context ()
{
pop_dollar_vars ();
kill_all_local_variables ();
variable_context--;
}
/* Save the existing positional parameters on a stack. */
void
push_dollar_vars ()
{
if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
{
dollar_arg_stack = (WORD_LIST **)
xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
* sizeof (WORD_LIST **));
}
dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
}
/* Restore the positional parameters from our stack. */
void
pop_dollar_vars ()
{
if (!dollar_arg_stack || dollar_arg_stack_index == 0)
return;
remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
}
void
dispose_saved_dollar_vars ()
{
if (!dollar_arg_stack || dollar_arg_stack_index == 0)
return;
dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
}
static int changed_dollar_vars;
/* Have the dollar variables been reset to new values since we last
@ -315,7 +340,12 @@ set_dollar_vars_unchanged ()
void
set_dollar_vars_changed ()
{
changed_dollar_vars = 1;
if (variable_context)
changed_dollar_vars |= ARGS_FUNC;
else if (this_shell_builtin == set_builtin)
changed_dollar_vars |= ARGS_SETBLTIN;
else
changed_dollar_vars |= ARGS_INVOC;
}
/* **************************************************************** */
@ -330,21 +360,24 @@ set_dollar_vars_changed ()
follow. If FATAL is true, call throw_to_top_level, which exits the
shell; if not, call jump_to_top_level (DISCARD), which aborts the
current command. */
long
intmax_t
get_numeric_arg (list, fatal)
WORD_LIST *list;
int fatal;
{
long count = 1;
intmax_t count = 1;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list)
{
register char *arg;
arg = list->word->word;
if (!arg || (legal_number (arg, &count) == 0))
if (arg == 0 || (legal_number (arg, &count) == 0))
{
builtin_error ("bad non-numeric arg `%s'", list->word->word);
sh_neednumarg (list->word->word);
if (fatal)
throw_to_top_level ();
else
@ -362,13 +395,19 @@ get_exitstat (list)
WORD_LIST *list;
{
int status;
long sval;
intmax_t sval;
char *arg;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list == 0)
return (last_command_exit_value);
arg = list->word->word;
if (arg == 0 || legal_number (arg, &sval) == 0)
{
builtin_error ("bad non-numeric arg `%s'", list->word->word);
sh_neednumarg (list->word->word ? list->word->word : "`'");
return 255;
}
no_args (list->next);
@ -460,13 +499,65 @@ set_working_directory (name)
/* **************************************************************** */
#if defined (JOB_CONTROL)
int
get_job_by_name (name, flags)
const char *name;
int flags;
{
register int i, wl, cl, match, job;
register PROCESS *p;
job = NO_JOB;
wl = strlen (name);
for (i = job_slots - 1; i >= 0; i--)
{
if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED))
continue;
p = jobs[i]->pipe;
do
{
if (flags & JM_EXACT)
{
cl = strlen (p->command);
match = STREQN (p->command, name, cl);
}
else if (flags & JM_SUBSTRING)
match = strindex (p->command, name) != (char *)0;
else
match = STREQN (p->command, name, wl);
if (match == 0)
{
p = p->next;
continue;
}
else if (flags & JM_FIRSTMATCH)
return i; /* return first match */
else if (job != NO_JOB)
{
if (this_shell_builtin)
builtin_error ("%s: ambiguous job spec", name);
else
report_error ("%s: ambiguous job spec", name);
return (DUP_JOB);
}
else
job = i;
}
while (p != jobs[i]->pipe);
}
return (job);
}
/* Return the job spec found in LIST. */
int
get_job_spec (list)
WORD_LIST *list;
{
register char *word;
int job, substring_search;
int job, jflags;
if (list == 0)
return (current_job);
@ -482,10 +573,14 @@ get_job_spec (list)
if (DIGIT (*word) && all_digits (word))
{
job = atoi (word);
#if 0
return (job >= job_slots ? NO_JOB : job - 1);
#else
return (job > job_slots ? NO_JOB : job - 1);
#endif
}
substring_search = 0;
jflags = 0;
switch (*word)
{
case 0:
@ -497,43 +592,12 @@ get_job_spec (list)
return (previous_job);
case '?': /* Substring search requested. */
substring_search++;
jflags |= JM_SUBSTRING;
word++;
/* FALLTHROUGH */
default:
{
register int i, wl;
job = NO_JOB;
wl = strlen (word);
for (i = 0; i < job_slots; i++)
{
if (jobs[i])
{
register PROCESS *p;
p = jobs[i]->pipe;
do
{
if ((substring_search && strindex (p->command, word)) ||
(STREQN (p->command, word, wl)))
{
if (job != NO_JOB)
{
builtin_error ("ambigious job spec: %s", word);
return (DUP_JOB);
}
else
job = i;
}
p = p->next;
}
while (p != jobs[i]->pipe);
}
}
return (job);
}
return get_job_by_name (word, jflags);
}
}
#endif /* JOB_CONTROL */
@ -546,7 +610,8 @@ display_signal_list (list, forcecols)
register int i, column;
char *name;
int result;
long signum;
int signum;
intmax_t lsignum;
result = EXECUTION_SUCCESS;
if (!list)
@ -581,20 +646,21 @@ display_signal_list (list, forcecols)
/* List individual signal names or numbers. */
while (list)
{
if (legal_number (list->word->word, &signum))
if (legal_number (list->word->word, &lsignum))
{
/* This is specified by Posix.2 so that exit statuses can be
mapped into signal numbers. */
if (signum > 128)
signum -= 128;
if (signum < 0 || signum >= NSIG)
if (lsignum > 128)
lsignum -= 128;
if (lsignum < 0 || lsignum >= NSIG)
{
builtin_error ("bad signal number: %s", list->word->word);
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
signum = lsignum;
name = signal_name (signum);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
{
@ -614,12 +680,12 @@ display_signal_list (list, forcecols)
signum = decode_signal (list->word->word);
if (signum == NO_SIG)
{
builtin_error ("%s: not a signal specification", list->word->word);
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
printf ("%ld\n", signum);
printf ("%d\n", signum);
}
list = list->next;
}