bash-20120629 remove leftover and stray files

This commit is contained in:
Chet Ramey
2012-07-07 12:26:34 -04:00
parent d42cb8c15b
commit 23477ba0d3
41 changed files with 0 additions and 75699 deletions
-659
View File
@@ -1,659 +0,0 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-aAfFgilnrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
display the attributes and values of all variables.
Options:
-f restrict action or display to function names and definitions
-F restrict display to function names only (plus line number and
source file when debugging)
-g create global variables when used in a shell function; otherwise
ignored
-p display the attributes and value of each NAME
Options which set attributes:
-a to make NAMEs indexed arrays (if supported)
-A to make NAMEs associative arrays (if supported)
-i to make NAMEs have the `integer' attribute
-l to convert NAMEs to lower case on assignment
-n make NAME a reference to the variable named by its value
-r to make NAMEs readonly
-t to make NAMEs have the `trace' attribute
-u to convert NAMEs to upper case on assignment
-x to make NAMEs export
Using `+' instead of `-' turns off the given attribute.
Variables with the integer attribute have arithmetic evaluation (see
the `let' command) performed when the variable is assigned a value.
When used in a function, `declare' makes NAMEs local, as with the `local'
command. The `-g' option suppresses this behavior.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
$END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ...
Set variable values and attributes.
Obsolete. See `help declare'.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
#include "builtext.h"
#include "bashgetopt.h"
extern int array_needs_making;
extern int posixly_correct;
static int declare_internal __P((register WORD_LIST *, int));
/* Declare or change variable attributes. */
int
declare_builtin (list)
register WORD_LIST *list;
{
return (declare_internal (list, 0));
}
$BUILTIN local
$FUNCTION local_builtin
$SHORT_DOC local [option] name[=value] ...
Define local variables.
Create a local variable called NAME, and give it VALUE. OPTION can
be any option accepted by `declare'.
Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.
Exit Status:
Returns success unless an invalid option is supplied, an error occurs,
or the shell is not executing a function.
$END
int
local_builtin (list)
register WORD_LIST *list;
{
if (variable_context)
return (declare_internal (list, 1));
else
{
builtin_error (_("can only be used in a function"));
return (EXECUTION_FAILURE);
}
}
#if defined (ARRAY_VARS)
# define DECLARE_OPTS "+acfgilnprtuxAF"
#else
# define DECLARE_OPTS "+cfgilnprtuxF"
#endif
/* The workhorse function. */
static int
declare_internal (list, local_var)
register WORD_LIST *list;
int local_var;
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal, onref, offref;
char *t, *subscript_start;
SHELL_VAR *var, *refvar;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
refvar = (SHELL_VAR *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
flags = list_opttype == '+' ? &flags_off : &flags_on;
switch (opt)
{
case 'a':
#if defined (ARRAY_VARS)
*flags |= att_array;
break;
#else
builtin_usage ();
return (EX_USAGE);
#endif
case 'A':
#if defined (ARRAY_VARS)
*flags |= att_assoc;
break;
#else
builtin_usage ();
return (EX_USAGE);
#endif
case 'p':
if (local_var == 0)
pflag++;
break;
case 'F':
nodefs++;
*flags |= att_function;
break;
case 'f':
*flags |= att_function;
break;
case 'g':
if (flags == &flags_on)
mkglobal = 1;
break;
case 'i':
*flags |= att_integer;
break;
case 'n':
*flags |= att_nameref;
break;
case 'r':
*flags |= att_readonly;
break;
case 't':
*flags |= att_trace;
break;
case 'x':
*flags |= att_exported;
array_needs_making = 1;
break;
#if defined (CASEMOD_ATTRS)
# if defined (CASEMOD_CAPCASE)
case 'c':
*flags |= att_capcase;
if (flags == &flags_on)
flags_off |= att_uppercase|att_lowercase;
break;
# endif
case 'l':
*flags |= att_lowercase;
if (flags == &flags_on)
flags_off |= att_capcase|att_uppercase;
break;
case 'u':
*flags |= att_uppercase;
if (flags == &flags_on)
flags_off |= att_capcase|att_lowercase;
break;
#endif /* CASEMOD_ATTRS */
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
/* If there are no more arguments left, then we just want to show
some variables. */
if (list == 0) /* declare -[aAfFirtx] */
{
/* Show local variables defined at this context level if this is
the `local' builtin. */
if (local_var)
{
register SHELL_VAR **vlist;
register int i;
vlist = all_local_variables ();
if (vlist)
{
for (i = 0; vlist[i]; i++)
print_assignment (vlist[i]);
free (vlist);
}
}
else if (pflag && (flags_on == 0 || flags_on == att_function))
show_all_var_attributes (flags_on == 0, nodefs);
else if (flags_on == 0)
return (set_builtin ((WORD_LIST *)NULL));
else
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
if (pflag) /* declare -p [-aAfFirtx] name [name...] */
{
for (any_failed = 0; list; list = list->next)
{
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
{
sh_notfound (list->word->word);
any_failed++;
}
}
return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS));
}
#define NEXT_VARIABLE() free (name); list = list->next; continue
/* There are arguments left, so we are making variables. */
while (list) /* declare [-aAfFirx] name [name ...] */
{
char *value, *name;
int offset, aflags;
#if defined (ARRAY_VARS)
int making_array_special, compound_array_assign, simple_array_assign;
#endif
name = savestring (list->word->word);
offset = assignment (name, 0);
aflags = 0;
if (offset) /* declare [-aAfFirx] name=value */
{
name[offset] = '\0';
value = name + offset + 1;
if (name[offset - 1] == '+')
{
aflags |= ASS_APPEND;
name[offset - 1] = '\0';
}
}
else
value = "";
#if defined (ARRAY_VARS)
compound_array_assign = simple_array_assign = 0;
subscript_start = (char *)NULL;
if (t = strchr (name, '[')) /* ] */
{
/* If offset != 0 we have already validated any array reference */
if (offset == 0 && valid_array_reference (name) == 0)
{
sh_invalidid (name);
assign_error++;
NEXT_VARIABLE ();
}
subscript_start = t;
*t = '\0';
making_array_special = 1;
}
else
making_array_special = 0;
#endif
/* If we're in posix mode or not looking for a shell function (since
shell function names don't have to be valid identifiers when the
shell's not in posix mode), check whether or not the argument is a
valid, well-formed shell identifier. */
if ((posixly_correct || (flags_on & att_function) == 0) && legal_identifier (name) == 0)
{
sh_invalidid (name);
assign_error++;
NEXT_VARIABLE ();
}
/* If VARIABLE_CONTEXT has a non-zero value, then we are executing
inside of a function. This means we should make local variables,
not global ones. */
/* XXX - this has consequences when we're making a local copy of a
variable that was in the temporary environment. Watch out
for this. */
refvar = (SHELL_VAR *)NULL;
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_local_assoc_variable (name);
else if ((flags_on & att_array) || making_array_special)
var = make_local_array_variable (name, making_array_special);
else
#endif
#if 0
/* XXX - this doesn't work right yet. */
/* See below for rationale for doing this. */
if (flags_on & att_nameref)
{
/* See if we are trying to modify an existing nameref variable */
var = find_variable_last_nameref (name);
if (var && nameref_p (var) == 0)
var = make_local_variable (name);
}
else if (flags_off & att_nameref)
{
var = (SHELL_VAR *)NULL;
/* See if we are trying to modify an existing nameref variable */
refvar = find_variable_last_nameref (name);
if (refvar && nameref_p (refvar) == 0)
refvar = 0;
if (refvar)
var = make_local_variable (nameref_cell (refvar));
if (var == 0)
var = make_local_variable (name);
}
else
#endif
var = make_local_variable (name);
if (var == 0)
{
any_failed++;
NEXT_VARIABLE ();
}
}
else
var = (SHELL_VAR *)NULL;
/* If we are declaring a function, then complain about it in some way.
We don't let people make functions by saying `typeset -f foo=bar'. */
/* There should be a way, however, to let people look at a particular
function definition by saying `typeset -f foo'. */
if (flags_on & att_function)
{
if (offset) /* declare -f [-rix] foo=bar */
{
builtin_error (_("cannot use `-f' to make functions"));
free (name);
return (EXECUTION_FAILURE);
}
else /* declare -f [-rx] name [name...] */
{
var = find_function (name);
if (var)
{
if (readonly_p (var) && (flags_off & att_readonly))
{
builtin_error (_("%s: readonly function"), name);
any_failed++;
NEXT_VARIABLE ();
}
/* declare -[Ff] name [name...] */
if (flags_on == att_function && flags_off == 0)
{
#if defined (DEBUGGER)
if (nodefs && debugging_mode)
{
shell_fn = find_function_def (var->name);
if (shell_fn)
printf ("%s %d %s\n", var->name, shell_fn->line, shell_fn->source_file);
else
printf ("%s\n", var->name);
}
else
#endif /* DEBUGGER */
{
t = nodefs ? var->name
: named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s\n", t);
any_failed = sh_chkwrite (any_failed);
}
}
else /* declare -[fF] -[rx] name [name...] */
{
VSETATTR (var, flags_on);
VUNSETATTR (var, flags_off);
}
}
else
any_failed++;
NEXT_VARIABLE ();
}
}
else /* declare -[aAirx] name [name...] */
{
/* Non-null if we just created or fetched a local variable. */
/* Here's what ksh93 seems to do. If we are modifying an existing
nameref variable, we don't follow the nameref chain past the last
nameref, and we set the nameref variable's value so future
references to that variable will return the value of the variable
we're assigning right now. */
if (var == 0 && (flags_on & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
var = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (var && nameref_p (var) == 0)
var = 0;
}
/* However, if we're turning off the nameref attribute on an existing
nameref variable, we first follow the nameref chain to the end,
modify the value of the variable this nameref variable references,
*CHANGING ITS VALUE AS A SIDE EFFECT* then turn off the nameref
flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */
else if (var == 0 && (flags_off & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (refvar && nameref_p (refvar) == 0)
refvar = 0;
if (refvar)
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
}
if (var == 0)
var = mkglobal ? find_global_variable (name) : find_variable (name);
if (var == 0)
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_new_assoc_variable (name);
else if ((flags_on & att_array) || making_array_special)
var = make_new_array_variable (name);
else
#endif
if (offset)
var = bind_variable (name, "", 0);
else
{
var = bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
}
/* Cannot use declare +r to turn off readonly attribute. */
if (readonly_p (var) && (flags_off & att_readonly))
{
sh_readonly (name);
any_failed++;
NEXT_VARIABLE ();
}
/* Cannot use declare to assign value to readonly or noassign
variable. */
if ((readonly_p (var) || noassign_p (var)) && offset)
{
if (readonly_p (var))
sh_readonly (name);
assign_error++;
NEXT_VARIABLE ();
}
#if defined (ARRAY_VARS)
if ((making_array_special || (flags_on & (att_array|att_assoc)) || array_p (var) || assoc_p (var)) && offset)
{
int vlen;
vlen = STRLEN (value);
if (value[0] == '(' && value[vlen-1] == ')')
compound_array_assign = 1;
else
simple_array_assign = 1;
}
/* Cannot use declare +a name or declare +A name to remove an
array variable. */
if (((flags_off & att_array) && array_p (var)) || ((flags_off & att_assoc) && assoc_p (var)))
{
builtin_error (_("%s: cannot destroy array variables in this way"), name);
any_failed++;
NEXT_VARIABLE ();
}
if ((flags_on & att_array) && assoc_p (var))
{
builtin_error (_("%s: cannot convert associative to indexed array"), name);
any_failed++;
NEXT_VARIABLE ();
}
if ((flags_on & att_assoc) && array_p (var))
{
builtin_error (_("%s: cannot convert indexed to associative array"), name);
any_failed++;
NEXT_VARIABLE ();
}
/* declare -A name[[n]] makes name an associative array variable. */
if (flags_on & att_assoc)
{
if (assoc_p (var) == 0)
var = convert_var_to_assoc (var);
}
/* declare -a name[[n]] or declare name[n] makes name an indexed
array variable. */
else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0)
var = convert_var_to_array (var);
#endif /* ARRAY_VARS */
/* XXX - we note that we are turning on nameref attribute and defer
setting it until the assignment has been made so we don't do an
inadvertent nameref lookup. Might have to do the same thing for
flags_off&att_nameref. */
/* XXX - ksh93 makes it an error to have a readonly nameref variable */
onref = (flags_on & att_nameref);
flags_on &= ~att_nameref;
if (array_p (var) || assoc_p (var)
|| (offset && compound_array_assign)
|| simple_array_assign)
onref = 0; /* array variables may not be namerefs */
/* ksh93 seems to do this */
offref = (flags_off & att_nameref);
flags_off &= ~att_nameref;
VSETATTR (var, flags_on);
VUNSETATTR (var, flags_off);
#if defined (ARRAY_VARS)
if (offset && compound_array_assign)
assign_array_var_from_string (var, value, aflags);
else if (simple_array_assign && subscript_start)
{
/* declare [-aA] name[N]=value */
*subscript_start = '['; /* ] */
var = assign_array_element (name, value, 0); /* XXX - not aflags */
*subscript_start = '\0';
if (var == 0) /* some kind of assignment error */
{
assign_error++;
flags_on |= onref;
flags_off |= offref;
NEXT_VARIABLE ();
}
}
else if (simple_array_assign)
{
/* let bind_{array,assoc}_variable take care of this. */
if (assoc_p (var))
bind_assoc_variable (var, name, savestring ("0"), value, aflags);
else
bind_array_variable (name, 0, value, aflags);
}
else
#endif
/* bind_variable_value duplicates the essential internals of
bind_variable() */
if (offset)
bind_variable_value (var, value, aflags);
/* If we found this variable in the temporary environment, as with
`var=value declare -x var', make sure it is treated identically
to `var=value export var'. Do the same for `declare -r' and
`readonly'. Preserve the attributes, except for att_tempvar. */
/* XXX -- should this create a variable in the global scope, or
modify the local variable flags? ksh93 has it modify the
global scope.
Need to handle case like in set_var_attribute where a temporary
variable is in the same table as the function local vars. */
if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
{
SHELL_VAR *tv;
char *tvalue;
tv = find_tempenv_variable (var->name);
if (tv)
{
tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
tv = bind_variable (var->name, tvalue, 0);
tv->attributes |= var->attributes & ~att_tempvar;
if (tv->context > 0)
VSETATTR (tv, att_propagate);
free (tvalue);
}
VSETATTR (var, att_propagate);
}
}
/* Turn on nameref attribute we deferred above. */
/* XXX - should we turn on the noassign attribute for consistency with
ksh93 when we turn on the nameref attribute? */
VSETATTR (var, onref);
flags_on |= onref;
VUNSETATTR (var, offref);
flags_off |= offref;
/* Yuck. ksh93 compatibility */
if (refvar)
VUNSETATTR (refvar, flags_off);
stupidly_hack_special_variables (name);
NEXT_VARIABLE ();
}
return (assign_error ? EX_BADASSIGN
: ((any_failed == 0) ? EXECUTION_SUCCESS
: EXECUTION_FAILURE));
}
-349
View File
@@ -1,349 +0,0 @@
/* evalfile.c - read and evaluate commands from a file or file descriptor */
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashtypes.h"
#include "posixstat.h"
#include "filecntl.h"
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../flags.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../trap.h"
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#include <typemax.h>
#include "common.h"
#if !defined (errno)
extern int errno;
#endif
/* Flags for _evalfile() */
#define FEVAL_ENOENTOK 0x001
#define FEVAL_BUILTIN 0x002
#define FEVAL_UNWINDPROT 0x004
#define FEVAL_NONINT 0x008
#define FEVAL_LONGJMP 0x010
#define FEVAL_HISTORY 0x020
#define FEVAL_CHECKBINARY 0x040
#define FEVAL_REGFILE 0x080
#define FEVAL_NOPUSHARGS 0x100
extern int posixly_correct;
extern int indirection_level, subshell_environment;
extern int return_catch_flag, return_catch_value;
extern int last_command_exit_value;
extern int executing_command_builtin;
/* How many `levels' of sourced files we have. */
int sourcelevel = 0;
static int
_evalfile (filename, flags)
const char *filename;
int flags;
{
volatile int old_interactive;
procenv_t old_return_catch;
int return_val, fd, result, pflags, i, nnull;
ssize_t nr; /* return value from read(2) */
char *string;
struct stat finfo;
size_t file_size;
sh_vmsg_func_t *errfunc;
#if defined (ARRAY_VARS)
SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
# if defined (DEBUGGER)
SHELL_VAR *bash_argv_v, *bash_argc_v;
ARRAY *bash_argv_a, *bash_argc_a;
# endif
char *t, tt[2];
#endif
char *lastcom;
USE_VAR(pflags);
#if defined (ARRAY_VARS)
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
# if defined (DEBUGGER)
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
# endif
#endif
fd = open (filename, O_RDONLY);
if (fd < 0 || (fstat (fd, &finfo) == -1))
{
file_error_and_exit:
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
file_error (filename);
if (flags & FEVAL_LONGJMP)
{
last_command_exit_value = 1;
jump_to_top_level (EXITPROG);
}
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
: ((errno == ENOENT) ? 0 : -1));
}
errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
if (S_ISDIR (finfo.st_mode))
{
(*errfunc) (_("%s: is a directory"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
{
(*errfunc) (_("%s: not a regular file"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
file_size = (size_t)finfo.st_size;
/* Check for overflow with large files. */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
(*errfunc) (_("%s: file is too large"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
{
string = (char *)xmalloc (1 + file_size);
nr = read (fd, string, file_size);
if (nr >= 0)
string[nr] = '\0';
}
else
nr = zmapfd (fd, &string, 0);
return_val = errno;
close (fd);
errno = return_val;
if (nr < 0) /* XXX was != file_size, not < 0 */
{
free (string);
goto file_error_and_exit;
}
if (nr == 0)
{
free (string);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
}
if ((flags & FEVAL_CHECKBINARY) &&
check_binary_file (string, (nr > 80) ? 80 : nr))
{
free (string);
(*errfunc) (_("%s: cannot execute binary file"), filename);
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
i = strlen (string);
if (i < nr)
{
for (nnull = i = 0; i < nr; i++)
if (string[i] == '\0')
{
memmove (string+i, string+i+1, nr - i);
nr--;
/* Even if the `check binary' flag is not set, we want to avoid
sourcing files with more than 256 null characters -- that
probably indicates a binary file. */
if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
{
free (string);
(*errfunc) (_("%s: cannot execute binary file"), filename);
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
}
}
if (flags & FEVAL_UNWINDPROT)
{
begin_unwind_frame ("_evalfile");
unwind_protect_int (return_catch_flag);
unwind_protect_jmp_buf (return_catch);
if (flags & FEVAL_NONINT)
unwind_protect_int (interactive);
unwind_protect_int (sourcelevel);
}
else
{
COPY_PROCENV (return_catch, old_return_catch);
if (flags & FEVAL_NONINT)
old_interactive = interactive;
}
if (flags & FEVAL_NONINT)
interactive = 0;
return_catch_flag++;
sourcelevel++;
#if defined (ARRAY_VARS)
array_push (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
array_push (bash_lineno_a, t);
free (t);
array_push (funcname_a, "source"); /* not exactly right */
# if defined (DEBUGGER)
/* Have to figure out a better way to do this when `source' is supplied
arguments */
if ((flags & FEVAL_NOPUSHARGS) == 0)
{
array_push (bash_argv_a, (char *)filename);
tt[0] = '1'; tt[1] = '\0';
array_push (bash_argc_a, tt);
}
# endif
#endif
/* set the flags to be passed to parse_and_execute */
pflags = SEVAL_RESETLINE;
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
if (flags & FEVAL_BUILTIN)
result = EXECUTION_SUCCESS;
return_val = setjmp (return_catch);
/* If `return' was seen outside of a function, but in the script, then
force parse_and_execute () to clean up. */
if (return_val)
{
parse_and_execute_cleanup ();
result = return_catch_value;
}
else
result = parse_and_execute (string, filename, pflags);
if (flags & FEVAL_UNWINDPROT)
run_unwind_frame ("_evalfile");
else
{
if (flags & FEVAL_NONINT)
interactive = old_interactive;
return_catch_flag--;
sourcelevel--;
COPY_PROCENV (old_return_catch, return_catch);
}
#if defined (ARRAY_VARS)
/* These two variables cannot be unset, and cannot be affected by the
sourced file. */
array_pop (bash_source_a);
array_pop (bash_lineno_a);
/* FUNCNAME can be unset, and so can potentially be changed by the
sourced file. */
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
if (nfv == funcname_v)
array_pop (funcname_a);
# if defined (DEBUGGER)
if ((flags & FEVAL_NOPUSHARGS) == 0)
{
array_pop (bash_argc_a);
array_pop (bash_argv_a);
}
# endif
#endif
return ((flags & FEVAL_BUILTIN) ? result : 1);
}
int
maybe_execute_file (fname, force_noninteractive)
const char *fname;
int force_noninteractive;
{
char *filename;
int result, flags;
filename = bash_tilde_expand (fname, 0);
flags = FEVAL_ENOENTOK;
if (force_noninteractive)
flags |= FEVAL_NONINT;
result = _evalfile (filename, flags);
free (filename);
return result;
}
#if defined (HISTORY)
int
fc_execute_file (filename)
const char *filename;
{
int flags;
/* We want these commands to show up in the history list if
remember_on_history is set. */
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
return (_evalfile (filename, flags));
}
#endif /* HISTORY */
int
source_file (filename, sflags)
const char *filename;
int sflags;
{
int flags, rval;
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
if (sflags)
flags |= FEVAL_NOPUSHARGS;
/* POSIX shells exit if non-interactive and file error. */
if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
flags |= FEVAL_LONGJMP;
rval = _evalfile (filename, flags);
run_return_trap ();
return rval;
}
-524
View File
@@ -1,524 +0,0 @@
/* evalstring.c - evaluate a string as one or more shell commands. */
/* Copyright (C) 1996-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include "filecntl.h"
#include "../bashansi.h"
#include "../shell.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../flags.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../redir.h"
#include "../trap.h"
#include "../bashintl.h"
#include <y.tab.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#include "common.h"
#include "builtext.h"
#if !defined (errno)
extern int errno;
#endif
#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
extern int indirection_level, subshell_environment;
extern int line_number, line_number_for_err_trap;
extern int current_token, shell_eof_token;
extern int last_command_exit_value;
extern int running_trap;
extern int loop_level;
extern int executing_list;
extern int comsub_ignore_return;
extern int posixly_correct;
extern sh_builtin_func_t *this_shell_builtin;
extern char *the_printed_command_except_trap;
int parse_and_execute_level = 0;
static int cat_file __P((REDIRECT *));
#define PE_TAG "parse_and_execute top"
#define PS_TAG "parse_string top"
#if defined (HISTORY)
static void
set_history_remembering ()
{
remember_on_history = enable_history_list;
}
#endif
static void
restore_lastcom (x)
char *x;
{
FREE (the_printed_command_except_trap);
the_printed_command_except_trap = x;
}
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
{
if (running_trap)
{
run_trap_cleanup (running_trap - 1);
unfreeze_jobs_list ();
}
if (have_unwind_protects ())
run_unwind_frame (PE_TAG);
else
parse_and_execute_level = 0; /* XXX */
}
static void
parse_prologue (string, flags, tag)
char *string;
int flags;
char *tag;
{
char *orig_string;
int x;
orig_string = string;
/* Unwind protect this invocation of parse_and_execute (). */
begin_unwind_frame (tag);
unwind_protect_int (parse_and_execute_level);
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (line_number_for_err_trap);
unwind_protect_int (loop_level);
unwind_protect_int (executing_list);
unwind_protect_int (comsub_ignore_return);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
#if defined (HISTORY)
if (parse_and_execute_level == 0)
add_unwind_protect (set_history_remembering, (char *)NULL);
else
unwind_protect_int (remember_on_history); /* can be used in scripts */
# if defined (BANG_HISTORY)
if (interactive_shell)
unwind_protect_int (history_expansion_inhibited);
# endif /* BANG_HISTORY */
#endif /* HISTORY */
if (interactive_shell)
{
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
if (the_printed_command_except_trap)
{
lastcom = savestring (the_printed_command_except_trap);
add_unwind_protect (restore_lastcom (lastcom));
}
add_unwind_protect (pop_stream, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
#if defined (HISTORY)
if (flags & SEVAL_NOHIST)
bash_history_disable ();
#endif /* HISTORY */
}
/* Parse and execute the commands in STRING. Returns whatever
execute_command () returns. This frees STRING. FLAGS is a
flags word; look in common.h for the possible values. Actions
are:
(flags & SEVAL_NONINT) -> interactive = 0;
(flags & SEVAL_INTERACT) -> interactive = 1;
(flags & SEVAL_NOHIST) -> call bash_history_disable ()
(flags & SEVAL_NOFREE) -> don't free STRING when finished
(flags & SEVAL_RESETLINE) -> reset line_number to 1
*/
int
parse_and_execute (string, from_file, flags)
char *string;
const char *from_file;
int flags;
{
int code, lreset;
volatile int should_jump_to_top_level, last_result;
COMMAND *volatile command;
parse_prologue (string, flags, PE_TAG);
parse_and_execute_level++;
lreset = flags & SEVAL_RESETLINE;
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (lreset);
if (lreset == 0)
line_number--;
indirection_level++;
code = should_jump_to_top_level = 0;
last_result = EXECUTION_SUCCESS;
with_input_from_string (string, from_file);
while (*(bash_input.location.string))
{
command = (COMMAND *)NULL;
if (interrupt_state)
{
last_result = EXECUTION_FAILURE;
break;
}
/* Provide a location for functions which `longjmp (top_level)' to
jump to. This prevents errors in substitution from restarting
the reader loop directly, for example. */
code = setjmp (top_level);
if (code)
{
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
case EXITPROG:
if (command)
run_unwind_frame ("pe_dispose");
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
should_jump_to_top_level = 1;
goto out;
case DISCARD:
if (command)
run_unwind_frame ("pe_dispose");
last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */
if (subshell_environment)
{
should_jump_to_top_level = 1;
goto out;
}
else
{
#if 0
dispose_command (command); /* pe_dispose does this */
#endif
continue;
}
default:
command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
break;
}
}
if (parse_command () == 0)
{
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
{
last_result = EXECUTION_SUCCESS;
dispose_command (global_command);
global_command = (COMMAND *)NULL;
}
else if (command = global_command)
{
struct fd_bitmap *bitmap;
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
add_unwind_protect (dispose_command, command); /* XXX */
global_command = (COMMAND *)NULL;
if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
command->flags |= CMD_IGNORE_RETURN;
#if defined (ONESHOT)
/*
* IF
* we were invoked as `bash -c' (startup_state == 2) AND
* parse_and_execute has not been called recursively AND
* we're not running a trap AND
* we have parsed the full command (string == '\0') AND
* we're not going to run the exit trap AND
* we have a simple command without redirections AND
* the command is not being timed AND
* the command's return status is not being inverted
* THEN
* tell the execution code that we don't need to fork
*/
if (startup_state == 2 && parse_and_execute_level == 1 &&
running_trap == 0 &&
*bash_input.location.string == '\0' &&
command->type == cm_simple &&
signal_is_trapped (EXIT_TRAP) == 0 &&
command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0))
{
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
#endif /* ONESHOT */
/* See if this is a candidate for $( <file ). */
if (startup_state == 2 &&
(subshell_environment & SUBSHELL_COMSUB) &&
*bash_input.location.string == '\0' &&
command->type == cm_simple && !command->redirects &&
(command->flags & CMD_TIME_PIPELINE) == 0 &&
command->value.Simple->words == 0 &&
command->value.Simple->redirects &&
command->value.Simple->redirects->next == 0 &&
command->value.Simple->redirects->instruction == r_input_direction &&
command->value.Simple->redirects->redirector.dest == 0)
{
int r;
r = cat_file (command->value.Simple->redirects);
last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
}
else
last_result = execute_command_internal
(command, 0, NO_PIPE, NO_PIPE, bitmap);
dispose_command (command);
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
}
}
else
{
last_result = EXECUTION_FAILURE;
if (interactive_shell == 0 && this_shell_builtin &&
(this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) &&
last_command_exit_value == EX_BADSYNTAX && posixly_correct)
{
should_jump_to_top_level = 1;
code = ERREXIT;
last_command_exit_value = EX_BADUSAGE;
}
/* Since we are shell compatible, syntax errors in a script
abort the execution of the script. Right? */
break;
}
}
out:
run_unwind_frame (PE_TAG);
if (interrupt_state && parse_and_execute_level == 0)
{
/* An interrupt during non-interactive execution in an
interactive shell (e.g. via $PROMPT_COMMAND) should
not cause the shell to exit. */
interactive = interactive_shell;
throw_to_top_level ();
}
if (should_jump_to_top_level)
jump_to_top_level (code);
return (last_result);
}
/* Parse a command contained in STRING according to FLAGS and return the
number of characters consumed from the string. If non-NULL, set *ENDP
to the position in the string where the parse ended. Used to validate
command substitutions during parsing to obey Posix rules about finding
the end of the command and balancing parens. */
int
parse_string (string, from_file, flags, endp)
char *string;
const char *from_file;
int flags;
char **endp;
{
int code, nc;
volatile int should_jump_to_top_level;
COMMAND *volatile command, *oglobal;
char *ostring;
parse_prologue (string, flags, PS_TAG);
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (0);
code = should_jump_to_top_level = 0;
oglobal = global_command;
ostring = string;
with_input_from_string (string, from_file);
while (*(bash_input.location.string))
{
command = (COMMAND *)NULL;
#if 0
if (interrupt_state)
break;
#endif
/* Provide a location for functions which `longjmp (top_level)' to
jump to. */
code = setjmp (top_level);
if (code)
{
#if defined (DEBUG)
itrace("parse_string: longjmp executed: code = %d", code);
#endif
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
case EXITPROG:
case DISCARD: /* XXX */
if (command)
dispose_command (command);
/* Remember to call longjmp (top_level) after the old
value for it is restored. */
should_jump_to_top_level = 1;
goto out;
default:
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
break;
}
}
if (parse_command () == 0)
{
dispose_command (global_command);
global_command = (COMMAND *)NULL;
}
else
{
if ((flags & SEVAL_NOLONGJMP) == 0)
{
should_jump_to_top_level = 1;
code = DISCARD;
}
else
reset_parser (); /* XXX - sets token_to_read */
break;
}
if (current_token == yacc_EOF || current_token == shell_eof_token)
break;
}
out:
global_command = oglobal;
nc = bash_input.location.string - ostring;
if (endp)
*endp = bash_input.location.string;
run_unwind_frame (PS_TAG);
if (should_jump_to_top_level)
jump_to_top_level (code);
return (nc);
}
/* Handle a $( < file ) command substitution. This expands the filename,
returning errors as appropriate, then just cats the file to the standard
output. */
static int
cat_file (r)
REDIRECT *r;
{
char *fn;
int fd, rval;
if (r->instruction != r_input_direction)
return -1;
/* Get the filename. */
if (posixly_correct && !interactive_shell)
disallow_filename_globbing++;
fn = redirection_expand (r->redirectee.filename);
if (posixly_correct && !interactive_shell)
disallow_filename_globbing--;
if (fn == 0)
{
redirection_error (r, AMBIGUOUS_REDIRECT);
return -1;
}
fd = open(fn, O_RDONLY);
if (fd < 0)
{
file_error (fn);
free (fn);
return -1;
}
rval = zcatfd (fd, 1, fn);
free (fn);
close (fd);
return (rval);
}
-1252
View File
File diff suppressed because it is too large Load Diff
-878
View File
@@ -1,878 +0,0 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES set.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../flags.h"
#include "common.h"
#include "bashgetopt.h"
#if defined (READLINE)
# include "../input.h"
# include "../bashline.h"
# include <readline/readline.h>
#endif
#if defined (HISTORY)
# include "../bashhist.h"
#endif
extern int posixly_correct, ignoreeof, eof_encountered_limit;
#if defined (HISTORY)
extern int dont_save_function_defs;
#endif
#if defined (READLINE)
extern int no_line_editing;
#endif /* READLINE */
$BUILTIN set
$FUNCTION set_builtin
$SHORT_DOC set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
Set or unset values of shell options and positional parameters.
Change the value of shell attributes and positional parameters, or
display the names and values of shell variables.
Options:
-a Mark variables which are modified or created for export.
-b Notify of job termination immediately.
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
-h Remember the location of commands as they are looked up.
-k All assignment arguments are placed in the environment for a
command, not just those that precede the command name.
-m Job control is enabled.
-n Read commands but do not execute them.
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand same as -B
#if defined (READLINE)
emacs use an emacs-style line editing interface
#endif /* READLINE */
errexit same as -e
errtrace same as -E
functrace same as -T
hashall same as -h
#if defined (BANG_HISTORY)
histexpand same as -H
#endif /* BANG_HISTORY */
#if defined (HISTORY)
history enable command history
#endif
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
#if defined (JOB_CONTROL)
monitor same as -m
#endif
noclobber same as -C
noexec same as -n
noglob same as -f
nolog currently accepted but ignored
#if defined (JOB_CONTROL)
notify same as -b
#endif
nounset same as -u
onecmd same as -t
physical same as -P
pipefail the return value of a pipeline is the status of
the last command to exit with a non-zero status,
or zero if no command exited with a non-zero status
posix change the behavior of bash where the default
operation differs from the Posix standard to
match the standard
privileged same as -p
verbose same as -v
#if defined (READLINE)
vi use a vi-style line editing interface
#endif /* READLINE */
xtrace same as -x
-p Turned on whenever the real and effective user ids do not match.
Disables processing of the $ENV file and importing of shell
functions. Turning this option off causes the effective uid and
gid to be set to the real uid and gid.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
#if defined (BRACE_EXPANSION)
-B the shell will perform brace expansion
#endif /* BRACE_EXPANSION */
-C If set, disallow existing regular files to be overwritten
by redirection of output.
-E If set, the ERR trap is inherited by shell functions.
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
by default when the shell is interactive.
#endif /* BANG_HISTORY */
-P If set, do not resolve symbolic links when executing commands
such as cd which change the current directory.
-T If set, the DEBUG trap is inherited by shell functions.
-- Assign any remaining arguments to the positional parameters.
If there are no remaining arguments, the positional parameters
are unset.
- Assign any remaining arguments to the positional parameters.
The -x and -v options are turned off.
Using + rather than - causes these flags to be turned off. The
flags can also be used upon invocation of the shell. The current
set of flags may be found in $-. The remaining n ARGs are positional
parameters and are assigned, in order, to $1, $2, .. $n. If no
ARGs are given, all shell variables are printed.
Exit Status:
Returns success unless an invalid option is given.
$END
typedef int setopt_set_func_t __P((int, char *));
typedef int setopt_get_func_t __P((char *));
static void print_minus_o_option __P((char *, int, int));
static void print_all_shell_variables __P((void));
static int set_ignoreeof __P((int, char *));
static int set_posix_mode __P((int, char *));
#if defined (READLINE)
static int set_edit_mode __P((int, char *));
static int get_edit_mode __P((char *));
#endif
#if defined (HISTORY)
static int bash_set_history __P((int, char *));
#endif
static const char * const on = "on";
static const char * const off = "off";
/* A struct used to match long options for set -o to the corresponding
option letter or internal variable. The functions can be called to
dynamically generate values. */
const struct {
char *name;
int letter;
int *variable;
setopt_set_func_t *set_func;
setopt_get_func_t *get_func;
} o_options[] = {
{ "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BRACE_EXPANSION)
{ "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
#if defined (READLINE)
{ "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
#endif
{ "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (BANG_HISTORY)
{ "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif /* BANG_HISTORY */
#if defined (HISTORY)
{ "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
#endif
{ "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
{ "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (JOB_CONTROL)
{ "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
{ "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (HISTORY)
{ "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
#if defined (JOB_CONTROL)
{ "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif /* JOB_CONTROL */
{ "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
{ "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (READLINE)
{ "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode },
#endif
{ "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
};
#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0]))
#define GET_BINARY_O_OPTION_VALUE(i, name) \
((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
: (*o_options[i].variable))
#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
: (*o_options[i].variable = (onoff == FLAG_ON)))
int
minus_o_option_value (name)
char *name;
{
register int i;
int *on_or_off;
for (i = 0; o_options[i].name; i++)
{
if (STREQ (name, o_options[i].name))
{
if (o_options[i].letter)
{
on_or_off = find_flag (o_options[i].letter);
return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
}
else
return (GET_BINARY_O_OPTION_VALUE (i, name));
}
}
return (-1);
}
#define MINUS_O_FORMAT "%-15s\t%s\n"
static void
print_minus_o_option (name, value, pflag)
char *name;
int value, pflag;
{
if (pflag == 0)
printf (MINUS_O_FORMAT, name, value ? on : off);
else
printf ("set %co %s\n", value ? '-' : '+', name);
}
void
list_minus_o_opts (mode, reusable)
int mode, reusable;
{
register int i;
int *on_or_off, value;
for (i = 0; o_options[i].name; i++)
{
if (o_options[i].letter)
{
value = 0;
on_or_off = find_flag (o_options[i].letter);
if (on_or_off == FLAG_UNKNOWN)
on_or_off = &value;
if (mode == -1 || mode == *on_or_off)
print_minus_o_option (o_options[i].name, *on_or_off, reusable);
}
else
{
value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
if (mode == -1 || mode == value)
print_minus_o_option (o_options[i].name, value, reusable);
}
}
}
char **
get_minus_o_opts ()
{
char **ret;
int i;
ret = strvec_create (N_O_OPTIONS + 1);
for (i = 0; o_options[i].name; i++)
ret[i] = o_options[i].name;
ret[i] = (char *)NULL;
return ret;
}
static int
set_ignoreeof (on_or_off, option_name)
int on_or_off;
char *option_name;
{
ignoreeof = on_or_off == FLAG_ON;
unbind_variable ("ignoreeof");
if (ignoreeof)
bind_variable ("IGNOREEOF", "10", 0);
else
unbind_variable ("IGNOREEOF");
sv_ignoreeof ("IGNOREEOF");
return 0;
}
static int
set_posix_mode (on_or_off, option_name)
int on_or_off;
char *option_name;
{
posixly_correct = on_or_off == FLAG_ON;
if (posixly_correct == 0)
unbind_variable ("POSIXLY_CORRECT");
else
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
return (0);
}
#if defined (READLINE)
/* Magic. This code `knows' how readline handles rl_editing_mode. */
static int
set_edit_mode (on_or_off, option_name)
int on_or_off;
char *option_name;
{
int isemacs;
if (on_or_off == FLAG_ON)
{
rl_variable_bind ("editing-mode", option_name);
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
isemacs = rl_editing_mode == 1;
if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
}
return 1-no_line_editing;
}
static int
get_edit_mode (name)
char *name;
{
return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
: no_line_editing == 0 && rl_editing_mode == 0);
}
#endif /* READLINE */
#if defined (HISTORY)
static int
bash_set_history (on_or_off, option_name)
int on_or_off;
char *option_name;
{
if (on_or_off == FLAG_ON)
{
enable_history_list = 1;
bash_history_enable ();
if (history_lines_this_session == 0)
load_history ();
}
else
{
enable_history_list = 0;
bash_history_disable ();
}
return (1 - enable_history_list);
}
#endif
int
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
register int i;
for (i = 0; o_options[i].name; i++)
{
if (STREQ (option_name, o_options[i].name))
{
if (o_options[i].letter == 0)
{
SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
return (EXECUTION_SUCCESS);
}
else
{
if (change_flag (o_options[i].letter, on_or_off) == FLAG_ERROR)
{
sh_invalidoptname (option_name);
return (EXECUTION_FAILURE);
}
else
return (EXECUTION_SUCCESS);
}
}
}
sh_invalidoptname (option_name);
return (EX_USAGE);
}
static void
print_all_shell_variables ()
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
/* POSIX.2 does not allow function names and definitions to be output when
`set' is invoked without options (PASC Interp #202). */
if (posixly_correct == 0)
{
vars = all_shell_functions ();
if (vars)
{
print_func_list (vars);
free (vars);
}
}
}
void
set_shellopts ()
{
char *value;
char tflag[N_O_OPTIONS];
int vsize, i, vptr, *ip, exported;
SHELL_VAR *v;
for (vsize = i = 0; o_options[i].name; i++)
{
tflag[i] = 0;
if (o_options[i].letter)
{
ip = find_flag (o_options[i].letter);
if (ip && *ip)
{
vsize += strlen (o_options[i].name) + 1;
tflag[i] = 1;
}
}
else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
{
vsize += strlen (o_options[i].name) + 1;
tflag[i] = 1;
}
}
value = (char *)xmalloc (vsize + 1);
for (i = vptr = 0; o_options[i].name; i++)
{
if (tflag[i])
{
strcpy (value + vptr, o_options[i].name);
vptr += strlen (o_options[i].name);
value[vptr++] = ':';
}
}
if (vptr)
vptr--; /* cut off trailing colon */
value[vptr] = '\0';
v = find_variable ("SHELLOPTS");
/* Turn off the read-only attribute so we can bind the new value, and
note whether or not the variable was exported. */
if (v)
{
VUNSETATTR (v, att_readonly);
exported = exported_p (v);
}
else
exported = 0;
v = bind_variable ("SHELLOPTS", value, 0);
/* Turn the read-only attribute back on, and turn off the export attribute
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
exported before we bound the new value. */
VSETATTR (v, att_readonly);
if (mark_modified_vars && exported == 0 && exported_p (v))
VUNSETATTR (v, att_exported);
free (value);
}
void
parse_shellopts (value)
char *value;
{
char *vname;
int vptr;
vptr = 0;
while (vname = extract_colon_unit (value, &vptr))
{
set_minus_o_option (FLAG_ON, vname);
free (vname);
}
}
void
initialize_shell_options (no_shellopts)
int no_shellopts;
{
char *temp;
SHELL_VAR *var;
if (no_shellopts == 0)
{
var = find_variable ("SHELLOPTS");
/* set up any shell options we may have inherited. */
if (var && imported_p (var))
{
temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
if (temp)
{
parse_shellopts (temp);
free (temp);
}
}
}
/* Set up the $SHELLOPTS variable. */
set_shellopts ();
}
/* Reset the values of the -o options that are not also shell flags. This is
called from execute_cmd.c:initialize_subshell() when setting up a subshell
to run an executable shell script without a leading `#!'. */
void
reset_shell_options ()
{
#if defined (HISTORY)
remember_on_history = enable_history_list = 1;
#endif
ignoreeof = 0;
}
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
int
set_builtin (list)
WORD_LIST *list;
{
int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
register char *arg;
char s[3];
if (list == 0)
{
print_all_shell_variables ();
return (sh_chkwrite (EXECUTION_SUCCESS));
}
/* Check validity of flag arguments. */
rv = EXECUTION_SUCCESS;
reset_internal_getopt ();
while ((flag_name = internal_getopt (list, optflags)) != -1)
{
switch (flag_name)
{
case '?':
builtin_usage ();
return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
default:
break;
}
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
for (force_assignment = opts_changed = 0; list; )
{
arg = list->word->word;
/* If the argument is `--' or `-' then signal the end of the list
and remember the remaining arguments. */
if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
{
list = list->next;
/* `set --' unsets the positional parameters. */
if (arg[1] == '-')
force_assignment = 1;
/* Until told differently, the old shell behaviour of
`set - [arg ...]' being equivalent to `set +xv [arg ...]'
stands. Posix.2 says the behaviour is marked as obsolescent. */
else
{
change_flag ('x', '+');
change_flag ('v', '+');
opts_changed = 1;
}
break;
}
if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
{
while (flag_name = *++arg)
{
if (flag_name == '?')
{
builtin_usage ();
return (EXECUTION_SUCCESS);
}
else if (flag_name == 'o') /* -+o option-name */
{
char *option_name;
WORD_LIST *opt;
opt = list->next;
if (opt == 0)
{
list_minus_o_opts (-1, (on_or_off == '+'));
rv = sh_chkwrite (rv);
continue;
}
option_name = opt->word->word;
if (option_name == 0 || *option_name == '\0' ||
*option_name == '-' || *option_name == '+')
{
list_minus_o_opts (-1, (on_or_off == '+'));
continue;
}
list = list->next; /* Skip over option name. */
opts_changed = 1;
if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
{
set_shellopts ();
return (r);
}
}
else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
s[0] = on_or_off;
s[1] = flag_name;
s[2] = '\0';
sh_invalidopt (s);
builtin_usage ();
set_shellopts ();
return (EXECUTION_FAILURE);
}
opts_changed = 1;
}
}
else
{
break;
}
list = list->next;
}
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
/* Set up new value of $SHELLOPTS */
if (opts_changed)
set_shellopts ();
return (rv);
}
$BUILTIN unset
$FUNCTION unset_builtin
$SHORT_DOC unset [-f] [-v] [name ...]
Unset values and attributes of shell variables and functions.
For each NAME, remove the corresponding variable or function.
Options:
-f treat each NAME as a shell function
-v treat each NAME as a shell variable
Without options, unset first tries to unset a variable, and if that fails,
tries to unset a function.
Some variables cannot be unset; also see `readonly'.
Exit Status:
Returns success unless an invalid option is given or a NAME is read-only.
$END
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
int
unset_builtin (list)
WORD_LIST *list;
{
int unset_function, unset_variable, unset_array, opt, any_failed;
char *name;
unset_function = unset_variable = unset_array = any_failed = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "fv")) != -1)
{
switch (opt)
{
case 'f':
unset_function = 1;
break;
case 'v':
unset_variable = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (unset_function && unset_variable)
{
builtin_error (_("cannot simultaneously unset a function and a variable"));
return (EXECUTION_FAILURE);
}
while (list)
{
SHELL_VAR *var;
int tem;
#if defined (ARRAY_VARS)
char *t;
#endif
name = list->word->word;
#if defined (ARRAY_VARS)
unset_array = 0;
if (!unset_function && valid_array_reference (name))
{
t = strchr (name, '[');
*t++ = '\0';
unset_array++;
}
#endif
/* Get error checking out of the way first. The low-level functions
just perform the unset, relying on the caller to verify. */
/* Bash allows functions with names which are not valid identifiers
to be created when not in posix mode, so check only when in posix
mode when unsetting a function. */
if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
{
sh_invalidid (name);
NEXT_VARIABLE ();
}
/* Only search for functions here if -f supplied. */
var = unset_function ? find_function (name) : find_variable (name);
/* Some variables (but not functions yet) cannot be unset, period. */
if (var && unset_function == 0 && non_unsettable_p (var))
{
builtin_error (_("%s: cannot unset"), name);
NEXT_VARIABLE ();
}
/* Posix.2 says try variables first, then functions. If we would
find a function after unsuccessfully searching for a variable,
note that we're acting on a function now as if -f were
supplied. The readonly check below takes care of it. */
if (var == 0 && unset_variable == 0 && unset_function == 0)
{
if (var = find_function (name))
unset_function = 1;
}
/* Posix.2 says that unsetting readonly variables is an error. */
if (var && readonly_p (var))
{
builtin_error (_("%s: cannot unset: readonly %s"),
name, unset_function ? "function" : "variable");
NEXT_VARIABLE ();
}
/* Unless the -f option is supplied, the name refers to a variable. */
#if defined (ARRAY_VARS)
if (var && unset_array)
{
if (array_p (var) == 0 && assoc_p (var) == 0)
{
builtin_error (_("%s: not an array variable"), name);
NEXT_VARIABLE ();
}
else
{
tem = unbind_array_element (var, t);
if (tem == -1)
any_failed++;
}
}
else
#endif /* ARRAY_VARS */
tem = unset_function ? unbind_func (name) : unbind_variable (name);
/* This is what Posix.2 says: ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
that name does not exist, a function by that name, if any,
shall be unset.'' */
if (tem == -1 && unset_function == 0 && unset_variable == 0)
tem = unbind_func (name);
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
was not previously set shall not be considered an error.'' */
if (unset_function == 0)
stupidly_hack_special_variables (name);
list = list->next;
}
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
-517
View File
@@ -1,517 +0,0 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES setattr.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
#include "bashgetopt.h"
extern int posixly_correct;
extern int array_needs_making;
extern char *this_command_name;
extern sh_builtin_func_t *this_shell_builtin;
#ifdef ARRAY_VARS
extern int declare_builtin __P((WORD_LIST *));
#endif
#define READONLY_OR_EXPORT \
(this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
$BUILTIN export
$FUNCTION export_builtin
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
Set export attribute for shell variables.
Marks each NAME for automatic export to the environment of subsequently
executed commands. If VALUE is supplied, assign VALUE before exporting.
Options:
-f refer to shell functions
-n remove the export property from each NAME
-p display a list of all exported variables and functions
An argument of `--' disables further option processing.
Exit Status:
Returns success unless an invalid option is given or NAME is invalid.
$END
/* For each variable name in LIST, make that variable appear in the
environment passed to simple commands. If there is no LIST, then
print all such variables. An argument of `-n' says to remove the
exported attribute from variables named in LIST. An argument of
-f indicates that the names present in LIST refer to functions. */
int
export_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_exported, 0));
}
$BUILTIN readonly
$FUNCTION readonly_builtin
$SHORT_DOC readonly [-aAf] [name[=value] ...] or readonly -p
Mark shell variables as unchangeable.
Mark each NAME as read-only; the values of these NAMEs may not be
changed by subsequent assignment. If VALUE is supplied, assign VALUE
before marking as read-only.
Options:
-a refer to indexed array variables
-A refer to associative array variables
-f refer to shell functions
-p display a list of all readonly variables and functions
An argument of `--' disables further option processing.
Exit Status:
Returns success unless an invalid option is given or NAME is invalid.
$END
/* For each variable name in LIST, make that variable readonly. Given an
empty LIST, print out all existing readonly variables. */
int
readonly_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_readonly, 0));
}
#if defined (ARRAY_VARS)
# define ATTROPTS "aAfnp"
#else
# define ATTROPTS "fnp"
#endif
/* For each variable name in LIST, make that variable have the specified
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
remaining names in LIST (doesn't work for readonly). */
int
set_or_show_attributes (list, attribute, nodefs)
register WORD_LIST *list;
int attribute, nodefs;
{
register SHELL_VAR *var;
int assign, undo, any_failed, assign_error, opt;
int functions_only, arrays_only, assoc_only;
int aflags;
char *name;
#if defined (ARRAY_VARS)
WORD_LIST *nlist, *tlist;
WORD_DESC *w;
#endif
functions_only = arrays_only = assoc_only = 0;
undo = any_failed = assign_error = 0;
/* Read arguments from the front of the list. */
reset_internal_getopt ();
while ((opt = internal_getopt (list, ATTROPTS)) != -1)
{
switch (opt)
{
case 'n':
undo = 1;
break;
case 'f':
functions_only = 1;
break;
#if defined (ARRAY_VARS)
case 'a':
arrays_only = 1;
break;
case 'A':
assoc_only = 1;
break;
#endif
case 'p':
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list)
{
if (attribute & att_exported)
array_needs_making = 1;
/* Cannot undo readonly status, silently disallowed. */
if (undo && (attribute & att_readonly))
attribute &= ~att_readonly;
while (list)
{
name = list->word->word;
if (functions_only) /* xxx -f name */
{
var = find_function (name);
if (var == 0)
{
builtin_error (_("%s: not a function"), name);
any_failed++;
}
else
SETVARATTR (var, attribute, undo);
list = list->next;
continue;
}
/* xxx [-np] name[=value] */
assign = assignment (name, 0);
aflags = 0;
if (assign)
{
name[assign] = '\0';
if (name[assign - 1] == '+')
{
aflags |= ASS_APPEND;
name[assign - 1] = '\0';
}
}
if (legal_identifier (name) == 0)
{
sh_invalidid (name);
if (assign)
assign_error++;
else
any_failed++;
list = list->next;
continue;
}
if (assign) /* xxx [-np] name=value */
{
name[assign] = '=';
if (aflags & ASS_APPEND)
name[assign - 1] = '+';
#if defined (ARRAY_VARS)
/* Let's try something here. Turn readonly -a xxx=yyy into
declare -ra xxx=yyy and see what that gets us. */
if (arrays_only || assoc_only)
{
tlist = list->next;
list->next = (WORD_LIST *)NULL;
w = arrays_only ? make_word ("-ra") : make_word ("-rA");
nlist = make_word_list (w, list);
opt = declare_builtin (nlist);
if (opt != EXECUTION_SUCCESS)
assign_error++;
list->next = tlist;
dispose_word (w);
free (nlist);
}
else
#endif
/* This word has already been expanded once with command
and parameter expansion. Call do_assignment_no_expand (),
which does not do command or parameter substitution. If
the assignment is not performed correctly, flag an error. */
if (do_assignment_no_expand (name) == 0)
assign_error++;
name[assign] = '\0';
if (aflags & ASS_APPEND)
name[assign - 1] = '\0';
}
set_var_attribute (name, attribute, undo);
list = list->next;
}
}
else
{
SHELL_VAR **variable_list;
register int i;
if ((attribute & att_function) || functions_only)
{
variable_list = all_shell_functions ();
if (attribute != att_function)
attribute &= ~att_function; /* so declare -xf works, for example */
}
else
variable_list = all_shell_variables ();
#if defined (ARRAY_VARS)
if (attribute & att_array)
{
arrays_only++;
if (attribute != att_array)
attribute &= ~att_array;
}
else if (attribute & att_assoc)
{
assoc_only++;
if (attribute != att_assoc)
attribute &= ~att_assoc;
}
#endif
if (variable_list)
{
for (i = 0; var = variable_list[i]; i++)
{
#if defined (ARRAY_VARS)
if (arrays_only && array_p (var) == 0)
continue;
else if (assoc_only && assoc_p (var) == 0)
continue;
#endif
if ((var->attributes & attribute))
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
}
free (variable_list);
}
}
return (assign_error ? EX_BADASSIGN
: ((any_failed == 0) ? EXECUTION_SUCCESS
: EXECUTION_FAILURE));
}
/* Show all variable variables (v == 1) or functions (v == 0) with
attributes. */
int
show_all_var_attributes (v, nodefs)
int v, nodefs;
{
SHELL_VAR **variable_list, *var;
int any_failed;
register int i;
variable_list = v ? all_shell_variables () : all_shell_functions ();
if (variable_list == 0)
return (EXECUTION_SUCCESS);
for (i = any_failed = 0; var = variable_list[i]; i++)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
free (variable_list);
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
don't show function definitions along with the name. If PATTR is
non-zero, it indicates we're being called from `export' or `readonly'.
In POSIX mode, this prints the name of the calling builtin (`export'
or `readonly') instead of `declare', and doesn't print function defs
when called by `export' or `readonly'. */
int
show_var_attributes (var, pattr, nodefs)
SHELL_VAR *var;
int pattr, nodefs;
{
char flags[16], *x;
int i;
i = 0;
/* pattr == 0 means we are called from `declare'. */
if (pattr == 0 || posixly_correct == 0)
{
#if defined (ARRAY_VARS)
if (array_p (var))
flags[i++] = 'a';
if (assoc_p (var))
flags[i++] = 'A';
#endif
if (function_p (var))
flags[i++] = 'f';
if (integer_p (var))
flags[i++] = 'i';
if (nameref_p (var))
flags[i++] = 'n';
if (readonly_p (var))
flags[i++] = 'r';
if (trace_p (var))
flags[i++] = 't';
if (exported_p (var))
flags[i++] = 'x';
if (capcase_p (var))
flags[i++] = 'c';
if (lowercase_p (var))
flags[i++] = 'l';
if (uppercase_p (var))
flags[i++] = 'u';
}
else
{
#if defined (ARRAY_VARS)
if (array_p (var))
flags[i++] = 'a';
if (assoc_p (var))
flags[i++] = 'A';
#endif
if (function_p (var))
flags[i++] = 'f';
}
flags[i] = '\0';
/* If we're printing functions with definitions, print the function def
first, then the attributes, instead of printing output that can't be
reused as input to recreate the current state. */
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
{
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
nodefs++;
if (pattr == 0 && i == 1 && flags[0] == 'f')
return 0; /* don't print `declare -f name' */
}
if (pattr == 0 || posixly_correct == 0)
printf ("declare -%s ", i ? flags : "-");
else if (i)
printf ("%s -%s ", this_command_name, flags);
else
printf ("%s ", this_command_name);
#if defined (ARRAY_VARS)
if (array_p (var))
print_array_assignment (var, 1);
else if (assoc_p (var))
print_assoc_assignment (var, 1);
else
#endif
/* force `readonly' and `export' to not print out function definitions
when in POSIX mode. */
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
printf ("%s\n", var->name);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
else if (invisible_p (var) || var_isset (var) == 0)
printf ("%s\n", var->name);
else
{
x = sh_double_quote (value_cell (var));
printf ("%s=%s\n", var->name, x);
free (x);
}
return (0);
}
int
show_name_attributes (name, nodefs)
char *name;
int nodefs;
{
SHELL_VAR *var;
var = find_variable_tempenv (name);
if (var && invisible_p (var) == 0)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
}
else
return (1);
}
void
set_var_attribute (name, attribute, undo)
char *name;
int attribute, undo;
{
SHELL_VAR *var, *tv;
char *tvalue;
if (undo)
var = find_variable (name);
else
{
tv = find_tempenv_variable (name);
/* XXX -- need to handle case where tv is a temp variable in a
function-scope context, since function_env has been merged into
the local variables table. */
if (tv && tempvar_p (tv))
{
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
var = bind_variable (tv->name, tvalue, 0);
var->attributes |= tv->attributes & ~att_tempvar;
VSETATTR (tv, att_propagate);
if (var->context != 0)
VSETATTR (var, att_propagate);
SETVARATTR (tv, attribute, undo); /* XXX */
stupidly_hack_special_variables (tv->name);
free (tvalue);
}
else
{
var = find_variable_notempenv (name);
if (var == 0)
{
var = bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
else if (var->context != 0)
VSETATTR (var, att_propagate);
}
}
if (var)
SETVARATTR (var, attribute, undo);
if (var && (exported_p (var) || (attribute & att_exported)))
array_needs_making++; /* XXX */
}
-199
View File
@@ -1,199 +0,0 @@
This file is source.def, from which is created source.c.
It implements the builtins "." and "source" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES source.c
$BUILTIN source
$FUNCTION source_builtin
$SHORT_DOC source filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
$END
$BUILTIN .
$DOCNAME dot
$FUNCTION source_builtin
$SHORT_DOC . filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
$END
#include <config.h>
#include "../bashtypes.h"
#include "posixstat.h"
#include "filecntl.h"
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include <errno.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../flags.h"
#include "../findcmd.h"
#include "common.h"
#include "bashgetopt.h"
#include "../trap.h"
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int posixly_correct;
extern int last_command_exit_value;
extern int executing_command_builtin;
extern char *the_printed_command_except_trap;
static void maybe_pop_dollar_vars __P((void));
/* If non-zero, `.' uses $PATH to look up the script to be sourced. */
int source_uses_path = 1;
/* If non-zero, `.' looks in the current directory if the filename argument
is not found in the $PATH. */
int source_searches_cwd = 1;
/* If this . script is supplied arguments, we save the dollar vars and
replace them with the script arguments for the duration of the script's
execution. If the script does not change the dollar vars, we restore
what we saved. If the dollar vars are changed in the script, and we are
not executing a shell function, we leave the new values alone and free
the saved values. */
static void
maybe_pop_dollar_vars ()
{
if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
dispose_saved_dollar_vars ();
else
pop_dollar_vars ();
if (debugging_mode)
pop_args (); /* restore BASH_ARGC and BASH_ARGV */
set_dollar_vars_unchanged ();
}
/* Read and execute commands from the file passed as argument. Guess what.
This cannot be done in a subshell, since things like variable assignments
take place in there. So, I open the file, place it into a large string,
close the file, and then execute the string. */
int
source_builtin (list)
WORD_LIST *list;
{
int result;
char *filename, *debug_trap;
if (no_options (list))
return (EX_USAGE);
list = loptend;
if (list == 0)
{
builtin_error (_("filename argument required"));
builtin_usage ();
return (EX_USAGE);
}
#if defined (RESTRICTED_SHELL)
if (restricted && strchr (list->word->word, '/'))
{
sh_restricted (list->word->word);
return (EXECUTION_FAILURE);
}
#endif
filename = (char *)NULL;
/* XXX -- should this be absolute_pathname? */
if (posixly_correct && strchr (list->word->word, '/'))
filename = savestring (list->word->word);
else if (absolute_pathname (list->word->word))
filename = savestring (list->word->word);
else if (source_uses_path)
filename = find_path_file (list->word->word);
if (filename == 0)
{
if (source_searches_cwd == 0)
{
builtin_error (_("%s: file not found"), list->word->word);
if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
{
last_command_exit_value = 1;
jump_to_top_level (EXITPROG);
}
return (EXECUTION_FAILURE);
}
else
filename = savestring (list->word->word);
}
begin_unwind_frame ("source");
add_unwind_protect ((Function *)xfree, filename);
if (list->next)
{
push_dollar_vars ();
add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
remember_args (list->next, 1);
if (debugging_mode)
push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
}
set_dollar_vars_unchanged ();
/* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
is set. XXX - should sourced files inherit the RETURN trap? Functions
don't. */
debug_trap = TRAP_STRING (DEBUG_TRAP);
if (debug_trap && function_trace_mode == 0)
{
debug_trap = savestring (debug_trap);
add_unwind_protect (xfree, debug_trap);
add_unwind_protect (set_debug_trap, debug_trap);
restore_default_signal (DEBUG_TRAP);
}
itrace("source_builtin: the printed command = %s", the_printed_command_except_trap);
result = source_file (filename, (list && list->next));
run_unwind_frame ("source");
return (result);
}