mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-11 20:50:42 +02:00
bash-4.4 beta2 release
This commit is contained in:
@@ -87,6 +87,7 @@ alias_builtin (list)
|
||||
pflag = 1;
|
||||
dflags |= AL_REUSABLE;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
+8
-1
@@ -1,7 +1,7 @@
|
||||
This file is cd.def, from which is created cd.c. It implements the
|
||||
builtins "cd" and "pwd" in Bash.
|
||||
|
||||
Copyright (C) 1987-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -329,6 +329,13 @@ cd_builtin (list)
|
||||
builtin_error (_("too many arguments"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
else if (list->word->word[0] == '\0')
|
||||
{
|
||||
builtin_error (_("null directory"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
|
||||
{
|
||||
|
||||
@@ -813,6 +813,7 @@ compopt_builtin (list)
|
||||
case 'E':
|
||||
Eflag = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
+183
-39
@@ -1,7 +1,7 @@
|
||||
This file is declare.def, from which is created declare.c.
|
||||
It implements the builtins "declare" and "local" in Bash.
|
||||
|
||||
Copyright (C) 1987-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -286,8 +286,8 @@ declare_internal (list, local_var)
|
||||
/* There are arguments left, so we are making variables. */
|
||||
while (list) /* declare [-aAfFirx] name [name ...] */
|
||||
{
|
||||
char *value, *name;
|
||||
int offset, aflags, wflags;
|
||||
char *value, *name, *oldname;
|
||||
int offset, aflags, wflags, created_var, namelen;
|
||||
#if defined (ARRAY_VARS)
|
||||
int making_array_special, compound_array_assign, simple_array_assign;
|
||||
int var_exists, array_exists, creating_array, array_subscript_assignment;
|
||||
@@ -297,6 +297,7 @@ declare_internal (list, local_var)
|
||||
wflags = list->word->flags;
|
||||
offset = assignment (name, 0);
|
||||
aflags = 0;
|
||||
created_var = 0;
|
||||
|
||||
if (local_var && variable_context && STREQ (name, "-"))
|
||||
{
|
||||
@@ -325,7 +326,7 @@ declare_internal (list, local_var)
|
||||
that is specific to nameref variables. */
|
||||
if (flags_on & att_nameref)
|
||||
{
|
||||
#if defined (ARRAY_VARIABLES)
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (name, 0))
|
||||
{
|
||||
builtin_error (_("%s: reference variable cannot be an array"), name);
|
||||
@@ -334,17 +335,22 @@ declare_internal (list, local_var)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* disallow self references at global scope */
|
||||
if (STREQ (name, value) && variable_context == 0)
|
||||
/* disallow self references at global scope, warn at function scope */
|
||||
if (check_selfref (name, value, 0))
|
||||
{
|
||||
builtin_error (_("%s: nameref variable self references not allowed"), name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
if (variable_context == 0)
|
||||
{
|
||||
builtin_error (_("%s: nameref variable self references not allowed"), name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else
|
||||
builtin_warning (_("%s: circular name reference"), name);
|
||||
}
|
||||
#if 0
|
||||
if (value && *value && legal_identifier (value) == 0)
|
||||
#if 1
|
||||
if (value && *value && (aflags & ASS_APPEND) == 0 && valid_nameref_value (value, 1) == 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid variable name for name reference"), value);
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
@@ -352,13 +358,15 @@ declare_internal (list, local_var)
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
restart_new_var_name:
|
||||
var_exists = array_exists = creating_array = 0;
|
||||
compound_array_assign = simple_array_assign = 0;
|
||||
array_subscript_assignment = 0;
|
||||
subscript_start = (char *)NULL;
|
||||
if (t = strchr (name, '[')) /* ] */
|
||||
{
|
||||
/* If offset != 0 we have already validated any array reference */
|
||||
/* If offset != 0 we have already validated any array reference
|
||||
because assignment() calls skipsubscript() */
|
||||
if (offset == 0 && valid_array_reference (name, 0) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
@@ -395,6 +403,7 @@ declare_internal (list, local_var)
|
||||
refvar = (SHELL_VAR *)NULL;
|
||||
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
|
||||
{
|
||||
/* check name for validity here? */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (flags_on & att_assoc)
|
||||
var = make_local_assoc_variable (name);
|
||||
@@ -402,12 +411,41 @@ declare_internal (list, local_var)
|
||||
var = make_local_array_variable (name, making_array_special);
|
||||
else
|
||||
#endif
|
||||
if (offset == 0 && (flags_on & att_nameref))
|
||||
{
|
||||
/* First look for refvar at current scope */
|
||||
refvar = find_variable_last_nameref (name, 1);
|
||||
var = find_variable (name);
|
||||
/* VARIABLE_CONTEXT != 0, so we are attempting to create or modify
|
||||
the attributes for a local variable at the same scope. If we've
|
||||
used a reference from a previous context to resolve VAR, we
|
||||
want to throw REFVAR and VAR away and create a new local var. */
|
||||
if (refvar && refvar->context != variable_context)
|
||||
{
|
||||
refvar = 0;
|
||||
var = make_local_variable (name);
|
||||
}
|
||||
else if (refvar && refvar->context == variable_context)
|
||||
var = refvar;
|
||||
/* Maybe we just want to create a new local variable */
|
||||
else if (var == 0 || var->context != variable_context)
|
||||
var = make_local_variable (name);
|
||||
/* otherwise we have a var at the right context */
|
||||
}
|
||||
else
|
||||
/* XXX - check name for validity here with valid_nameref_value */
|
||||
var = make_local_variable (name); /* sets att_invisible for new vars */
|
||||
if (var == 0)
|
||||
{
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
if (var && nameref_p (var) && readonly_p (var) && nameref_cell (var) && (flags_off & att_nameref))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else
|
||||
var = (SHELL_VAR *)NULL;
|
||||
@@ -471,18 +509,33 @@ declare_internal (list, local_var)
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else /* declare -[aAirx] name [name...] */
|
||||
else /* declare -[aAinrx] name [name...] */
|
||||
{
|
||||
/* Non-null if we just created or fetched a local variable. */
|
||||
#if 0
|
||||
/* This is bash-4.3 code. */
|
||||
/* 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. */
|
||||
#else
|
||||
/* Here's what ksh93 seems to do as of the 2012 version: if we are
|
||||
using declare -n to modify the value of an existing nameref
|
||||
variable, don't follow the nameref chain at all and just search
|
||||
for a nameref at the current context. If we have a nameref,
|
||||
modify its value (changing which variable it references). */
|
||||
#endif
|
||||
if (var == 0 && (flags_on & att_nameref))
|
||||
{
|
||||
#if 0
|
||||
/* See if we are trying to modify an existing nameref variable */
|
||||
var = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
|
||||
var = mkglobal ? find_global_variable_last_nameref (name, 1) : find_variable_last_nameref (name, 1);
|
||||
#else
|
||||
/* See if we are trying to modify an existing nameref variable,
|
||||
but don't follow the nameref chain. */
|
||||
var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name);
|
||||
#endif
|
||||
if (var && nameref_p (var) == 0)
|
||||
var = 0;
|
||||
}
|
||||
@@ -494,12 +547,37 @@ declare_internal (list, local_var)
|
||||
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);
|
||||
refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0);
|
||||
if (refvar && nameref_p (refvar) == 0)
|
||||
refvar = 0;
|
||||
/* If the nameref is readonly but doesn't have a value, ksh93
|
||||
allows the nameref attribute to be removed. If it's readonly
|
||||
and has a value, even if the value doesn't reference an
|
||||
existing variable, we disallow the modification */
|
||||
if (refvar && nameref_cell (refvar) && readonly_p (refvar))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
if (refvar)
|
||||
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
|
||||
}
|
||||
#if defined (ARRAY_VARS)
|
||||
/* If we have an array assignment to a nameref, remove the nameref
|
||||
attribute and go on. */
|
||||
else if (var == 0 && offset && array_subscript_assignment)
|
||||
{
|
||||
var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name);
|
||||
if (var && nameref_p (var))
|
||||
{
|
||||
internal_warning (_("%s: removing nameref attribute"), name);
|
||||
FREE (value_cell (var)); /* XXX - bash-4.3 compat */
|
||||
var_setvalue (var, (char *)NULL);
|
||||
VUNSETATTR (var, att_nameref);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* See if we are trying to set flags or value for an existing nameref
|
||||
that points to a non-existent variable: e.g.,
|
||||
@@ -510,15 +588,57 @@ declare_internal (list, local_var)
|
||||
declare -p foo */
|
||||
if (var == 0 && (flags_on || flags_off || offset))
|
||||
{
|
||||
refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
|
||||
refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0);
|
||||
if (refvar && nameref_p (refvar) == 0)
|
||||
refvar = 0;
|
||||
if (refvar)
|
||||
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
|
||||
if (refvar && var == 0)
|
||||
{
|
||||
free (name);
|
||||
name = savestring (nameref_cell (refvar));
|
||||
oldname = name; /* need to free this */
|
||||
|
||||
namelen = strlen (nameref_cell (refvar));
|
||||
#if defined (ARRAY_VARS)
|
||||
if (subscript_start)
|
||||
{
|
||||
*subscript_start = '['; /*]*/
|
||||
namelen += strlen (subscript_start);
|
||||
}
|
||||
#endif
|
||||
name = xmalloc (namelen + 2 + strlen (value) + 1);
|
||||
strcpy (name, nameref_cell (refvar));
|
||||
#if defined (ARRAY_VARS)
|
||||
if (subscript_start)
|
||||
strcpy (name + strlen (nameref_cell (refvar)), subscript_start);
|
||||
#endif
|
||||
/* We are committed to using the new name, so reset */
|
||||
if (offset)
|
||||
{
|
||||
/* Rebuild assignment and restore offset and value */
|
||||
if (aflags & ASS_APPEND)
|
||||
name[namelen++] = '+';
|
||||
name[namelen++] = '=';
|
||||
if (value && *value)
|
||||
strcpy (name + namelen, value);
|
||||
else
|
||||
name[namelen] = '\0';
|
||||
offset = assignment (name, 0);
|
||||
/* if offset was valid previously, but the substituting
|
||||
of the nameref value results in an invalid assignment,
|
||||
throw an invalid identifier error */
|
||||
if (offset == 0)
|
||||
{
|
||||
free (oldname);
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
name[offset] = '\0';
|
||||
value = name + namelen;
|
||||
}
|
||||
free (oldname);
|
||||
goto restart_new_var_name;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
if (var == 0)
|
||||
@@ -547,12 +667,9 @@ declare_internal (list, local_var)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (offset)
|
||||
var = mkglobal ? bind_global_variable (name, "", 0) : bind_variable (name, "", 0);
|
||||
else
|
||||
{
|
||||
var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0);
|
||||
if (var && no_invisible_vars == 0)
|
||||
var = mkglobal ? bind_global_variable (name, (char *)NULL, ASS_FORCE) : bind_variable (name, (char *)NULL, ASS_FORCE);
|
||||
if (var && offset == 0 && no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
if (var == 0)
|
||||
@@ -560,6 +677,7 @@ declare_internal (list, local_var)
|
||||
/* Has to appear in brackets */
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
created_var = 1;
|
||||
}
|
||||
/* Can't take an existing array variable and make it a nameref */
|
||||
else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref))
|
||||
@@ -568,16 +686,30 @@ declare_internal (list, local_var)
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else if (nameref_p (var) && (flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0 && offset && valid_nameref_value (value, 1) == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else if (flags_on & att_nameref)
|
||||
{
|
||||
#if 0
|
||||
if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) == 0 && legal_identifier (value_cell (var)) == 0)
|
||||
#if 1
|
||||
/* Check of offset is to allow an assignment to a nameref var as
|
||||
part of the declare word to override existing value */
|
||||
if (nameref_p (var) == 0 && var_isset (var) && offset == 0 && valid_nameref_value (value_cell (var), 0) == 0)
|
||||
{
|
||||
builtin_error (_("%s: invalid variable name for name reference"), value_cell (var));
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value_cell (var));
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
#endif
|
||||
if (readonly_p (var))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
/* ksh93 compat: turning on nameref attribute turns off -ilu */
|
||||
VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase);
|
||||
}
|
||||
@@ -585,7 +717,7 @@ declare_internal (list, local_var)
|
||||
/* Cannot use declare +r to turn off readonly attribute. */
|
||||
if (readonly_p (var) && (flags_off & att_readonly))
|
||||
{
|
||||
sh_readonly (name);
|
||||
sh_readonly (name_cell (var));
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
@@ -685,14 +817,14 @@ declare_internal (list, local_var)
|
||||
VUNSETATTR (var, flags_off);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
aflags |= ASS_FORCE;
|
||||
if (offset && compound_array_assign)
|
||||
assign_array_var_from_string (var, value, aflags);
|
||||
assign_array_var_from_string (var, value, aflags|ASS_FORCE);
|
||||
else if (simple_array_assign && subscript_start)
|
||||
{
|
||||
/* declare [-aA] name[N]=value */
|
||||
*subscript_start = '['; /* ] */
|
||||
var = assign_array_element (name, value, 0); /* XXX - not aflags */
|
||||
/* XXX - problem here with appending */
|
||||
var = assign_array_element (name, value, aflags&ASS_APPEND); /* XXX - not aflags */
|
||||
*subscript_start = '\0';
|
||||
if (var == 0) /* some kind of assignment error */
|
||||
{
|
||||
@@ -706,25 +838,30 @@ declare_internal (list, local_var)
|
||||
{
|
||||
/* let bind_{array,assoc}_variable take care of this. */
|
||||
if (assoc_p (var))
|
||||
bind_assoc_variable (var, name, savestring ("0"), value, aflags);
|
||||
bind_assoc_variable (var, name, savestring ("0"), value, aflags|ASS_FORCE);
|
||||
else
|
||||
bind_array_variable (name, 0, value, aflags);
|
||||
bind_array_variable (name, 0, value, aflags|ASS_FORCE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* XXX - no ASS_FORCE here */
|
||||
/* bind_variable_value duplicates the essential internals of
|
||||
bind_variable() */
|
||||
if (offset)
|
||||
{
|
||||
if (onref)
|
||||
if (onref || nameref_p (var))
|
||||
aflags |= ASS_NAMEREF;
|
||||
v = bind_variable_value (var, value, aflags);
|
||||
if (v == 0 && onref)
|
||||
if (v == 0 && (onref || nameref_p (var)))
|
||||
{
|
||||
sh_invalidid (value);
|
||||
if (valid_nameref_value (value, 1) == 0)
|
||||
sh_invalidid (value);
|
||||
assign_error++;
|
||||
/* XXX - unset this variable? or leave it as normal var? */
|
||||
delete_var (var->name, mkglobal ? global_variables : shell_variables);
|
||||
if (created_var)
|
||||
delete_var (var->name, mkglobal ? global_variables : shell_variables);
|
||||
flags_on |= onref; /* undo change from above */
|
||||
flags_off |= offref;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
@@ -764,9 +901,16 @@ declare_internal (list, local_var)
|
||||
flags_on |= onref;
|
||||
VUNSETATTR (var, offref);
|
||||
flags_off |= offref;
|
||||
/* Yuck. ksh93 compatibility */
|
||||
/* Yuck. ksh93 compatibility. XXX - need to investigate more but
|
||||
definitely happens when turning off nameref attribute on nameref
|
||||
(see comments above). Under no circumstances allow this to turn
|
||||
off readonly attribute on readonly nameref variable. */
|
||||
if (refvar)
|
||||
VUNSETATTR (refvar, flags_off);
|
||||
{
|
||||
if (flags_off & att_readonly)
|
||||
flags_off &= ~att_readonly;
|
||||
VUNSETATTR (refvar, flags_off);
|
||||
}
|
||||
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
|
||||
@@ -104,7 +104,12 @@ should_suppress_fork (command)
|
||||
running_trap == 0 &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple &&
|
||||
#if 0
|
||||
signal_is_trapped (EXIT_TRAP) == 0 &&
|
||||
signal_is_trapped (ERROR_TRAP) == 0 &&
|
||||
#else
|
||||
any_signals_trapped () < 0 &&
|
||||
#endif
|
||||
command->redirects == 0 && command->value.Simple->redirects == 0 &&
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
||||
((command->flags & CMD_INVERT_RETURN) == 0));
|
||||
@@ -262,6 +267,7 @@ parse_and_execute (string, from_file, flags)
|
||||
current_token = '\n'; /* reset_parser() ? */
|
||||
|
||||
with_input_from_string (string, from_file);
|
||||
clear_shell_input_line ();
|
||||
while (*(bash_input.location.string))
|
||||
{
|
||||
command = (COMMAND *)NULL;
|
||||
@@ -384,7 +390,8 @@ parse_and_execute (string, from_file, flags)
|
||||
* 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
|
||||
* the command's return status is not being inverted AND
|
||||
* there aren't any traps in effect
|
||||
* THEN
|
||||
* tell the execution code that we don't need to fork
|
||||
*/
|
||||
@@ -491,7 +498,7 @@ parse_string (string, from_file, flags, endp)
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &ps_sigmask);
|
||||
#endif
|
||||
|
||||
/* itrace("parse_string: `%s'", string); */
|
||||
/*itrace("parse_string: `%s'", string);*/
|
||||
/* 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
|
||||
|
||||
@@ -447,6 +447,13 @@ fc_builtin (list)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#if defined (READLINE)
|
||||
/* If we're executing as part of a dispatched readline commnand like
|
||||
{emacs,vi}_edit_and_execute_command, the readline state will indicate it.
|
||||
We could remove the partial command from the history, but ksh93 doesn't
|
||||
so we stay compatible. */
|
||||
#endif
|
||||
|
||||
/* Make sure parse_and_execute doesn't turn this off, even though a
|
||||
call to parse_and_execute farther up the function call stack (e.g.,
|
||||
if this is called by vi_edit_and_execute_command) may have already
|
||||
|
||||
+16
-3
@@ -74,6 +74,7 @@ $END
|
||||
#endif
|
||||
|
||||
#include "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
@@ -86,6 +87,7 @@ $END
|
||||
|
||||
extern char *this_command_name;
|
||||
|
||||
static int getopts_unbind_variable __P((char *));
|
||||
static int getopts_bind_variable __P((char *, char *));
|
||||
static int dogetopts __P((int, char **));
|
||||
|
||||
@@ -99,6 +101,17 @@ getopts_reset (newind)
|
||||
sh_badopt = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getopts_unbind_variable (name)
|
||||
char *name;
|
||||
{
|
||||
#if 0
|
||||
return (unbind_variable (name));
|
||||
#else
|
||||
return (unbind_variable_noref (name));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
getopts_bind_variable (name, value)
|
||||
char *name, *value;
|
||||
@@ -253,7 +266,7 @@ dogetopts (argc, argv)
|
||||
|
||||
if (ret == G_EOF)
|
||||
{
|
||||
unbind_variable ("OPTARG");
|
||||
getopts_unbind_variable ("OPTARG");
|
||||
getopts_bind_variable (name, "?");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
@@ -270,7 +283,7 @@ dogetopts (argc, argv)
|
||||
bind_variable ("OPTARG", strval, 0);
|
||||
}
|
||||
else
|
||||
unbind_variable ("OPTARG");
|
||||
getopts_unbind_variable ("OPTARG");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -289,7 +302,7 @@ dogetopts (argc, argv)
|
||||
else
|
||||
{
|
||||
ret = getopts_bind_variable (name, "?");
|
||||
unbind_variable ("OPTARG");
|
||||
getopts_unbind_variable ("OPTARG");
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@ disown_builtin (list)
|
||||
case 'r':
|
||||
running_jobs = 1;
|
||||
break;
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
||||
@@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
|
||||
It implements the builtin "mapfile" in Bash.
|
||||
|
||||
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
||||
+3
-2
@@ -797,9 +797,10 @@ assign_vars:
|
||||
}
|
||||
else
|
||||
var = bind_variable ("REPLY", input_string, 0);
|
||||
VUNSETATTR (var, att_invisible);
|
||||
if (readonly_p (var) || noassign_p (var))
|
||||
if (var == 0 || readonly_p (var) || noassign_p (var))
|
||||
retval = EXECUTION_FAILURE;
|
||||
else
|
||||
VUNSETATTR (var, att_invisible);
|
||||
|
||||
xfree (input_string);
|
||||
return (retval);
|
||||
|
||||
@@ -145,7 +145,7 @@ to indices 0 and 1 of an array variable NAME in the executing shell.
|
||||
The default NAME is "COPROC".
|
||||
|
||||
Exit Status:
|
||||
Returns the exit status of COMMAND.
|
||||
The coproc command returns an exit status of 0.
|
||||
$END
|
||||
|
||||
$BUILTIN function
|
||||
|
||||
+37
-12
@@ -183,7 +183,9 @@ static int previous_option_value;
|
||||
|
||||
/* 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. */
|
||||
dynamically generate values. If you add a new variable name here
|
||||
that doesn't have a corresponding single-character option letter, make
|
||||
sure to set the value appropriately in reset_shell_options. */
|
||||
const struct {
|
||||
char *name;
|
||||
int letter;
|
||||
@@ -365,11 +367,11 @@ set_ignoreeof (on_or_off, option_name)
|
||||
char *option_name;
|
||||
{
|
||||
ignoreeof = on_or_off == FLAG_ON;
|
||||
unbind_variable ("ignoreeof");
|
||||
unbind_variable_noref ("ignoreeof");
|
||||
if (ignoreeof)
|
||||
bind_variable ("IGNOREEOF", "10", 0);
|
||||
else
|
||||
unbind_variable ("IGNOREEOF");
|
||||
unbind_variable_noref ("IGNOREEOF");
|
||||
sv_ignoreeof ("IGNOREEOF");
|
||||
return 0;
|
||||
}
|
||||
@@ -381,7 +383,7 @@ set_posix_mode (on_or_off, option_name)
|
||||
{
|
||||
posixly_correct = on_or_off == FLAG_ON;
|
||||
if (posixly_correct == 0)
|
||||
unbind_variable ("POSIXLY_CORRECT");
|
||||
unbind_variable_noref ("POSIXLY_CORRECT");
|
||||
else
|
||||
bind_variable ("POSIXLY_CORRECT", "y", 0);
|
||||
sv_strict_posix ("POSIXLY_CORRECT");
|
||||
@@ -623,10 +625,18 @@ initialize_shell_options (no_shellopts)
|
||||
void
|
||||
reset_shell_options ()
|
||||
{
|
||||
pipefail_opt = 0;
|
||||
ignoreeof = 0;
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
posixly_correct = 1;
|
||||
#else
|
||||
posixly_correct = 0;
|
||||
#endif
|
||||
#if defined (HISTORY)
|
||||
dont_save_function_defs = 0;
|
||||
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,
|
||||
@@ -798,7 +808,7 @@ unset_builtin (list)
|
||||
{
|
||||
int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
|
||||
int global_unset_func, global_unset_var;
|
||||
char *name;
|
||||
char *name, *tname;
|
||||
|
||||
unset_function = unset_variable = unset_array = nameref = any_failed = 0;
|
||||
global_unset_func = global_unset_var = 0;
|
||||
@@ -849,7 +859,7 @@ unset_builtin (list)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
unset_array = 0;
|
||||
if (!unset_function && valid_array_reference (name, 0))
|
||||
if (!unset_function && nameref == 0 && valid_array_reference (name, 0))
|
||||
{
|
||||
t = strchr (name, '[');
|
||||
*t++ = '\0';
|
||||
@@ -870,7 +880,7 @@ unset_builtin (list)
|
||||
|
||||
/* Only search for functions here if -f supplied. */
|
||||
var = unset_function ? find_function (name)
|
||||
: (nameref ? find_variable_last_nameref (name) : find_variable (name));
|
||||
: (nameref ? find_variable_last_nameref (name, 0) : find_variable (name));
|
||||
|
||||
/* Some variables (but not functions yet) cannot be unset, period. */
|
||||
if (var && unset_function == 0 && non_unsettable_p (var))
|
||||
@@ -887,7 +897,7 @@ unset_builtin (list)
|
||||
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 == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0)
|
||||
{
|
||||
if (var = find_function (name))
|
||||
unset_function = 1;
|
||||
@@ -921,8 +931,23 @@ unset_builtin (list)
|
||||
variable, make sure we still try to unset the nameref's value */
|
||||
if (var == 0 && nameref == 0 && unset_function == 0)
|
||||
{
|
||||
var = find_variable_last_nameref (name);
|
||||
tem = (var && nameref_p (var)) ? unbind_variable (nameref_cell (var)) : unbind_variable (name);
|
||||
var = find_variable_last_nameref (name, 0);
|
||||
if (var && nameref_p (var))
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (nameref_cell (var), 0))
|
||||
{
|
||||
tname = savestring (nameref_cell (var));
|
||||
if (var = array_variable_part (tname, &t, 0))
|
||||
tem = unbind_array_element (var, t);
|
||||
free (tname);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
tem = unbind_variable (nameref_cell (var));
|
||||
}
|
||||
else
|
||||
tem = unbind_variable (name);
|
||||
}
|
||||
else
|
||||
tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
|
||||
@@ -931,7 +956,7 @@ unset_builtin (list)
|
||||
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)
|
||||
if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0)
|
||||
tem = unbind_func (name);
|
||||
|
||||
name = list->word->word; /* reset above for namerefs */
|
||||
|
||||
+20
-3
@@ -538,8 +538,8 @@ set_var_attribute (name, attribute, undo)
|
||||
char *name;
|
||||
int attribute, undo;
|
||||
{
|
||||
SHELL_VAR *var, *tv, *v;
|
||||
char *tvalue;
|
||||
SHELL_VAR *var, *tv, *v, *refvar;
|
||||
char *tvalue, *refname;
|
||||
|
||||
if (undo)
|
||||
var = find_variable (name);
|
||||
@@ -554,6 +554,11 @@ set_var_attribute (name, attribute, undo)
|
||||
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
|
||||
|
||||
var = bind_variable (tv->name, tvalue, 0);
|
||||
if (var == 0)
|
||||
{
|
||||
free (tvalue);
|
||||
return; /* XXX - no error message here */
|
||||
}
|
||||
var->attributes |= tv->attributes & ~att_tempvar;
|
||||
/* This avoids an error message when propagating a read-only var
|
||||
later on. */
|
||||
@@ -578,10 +583,22 @@ set_var_attribute (name, attribute, undo)
|
||||
else
|
||||
{
|
||||
var = find_variable_notempenv (name);
|
||||
if (var == 0)
|
||||
{
|
||||
/* We might have a nameref pointing to something that we can't
|
||||
resolve to a shell variable. If we do, skip it. We do a little
|
||||
checking just so we can print an error message. */
|
||||
refvar = find_variable_nameref_for_create (name, 0);
|
||||
if (refvar == INVALID_NAMEREF_VALUE)
|
||||
return;
|
||||
/* Otherwise we probably have a nameref pointing to a variable
|
||||
that hasn't been created yet. bind_variable will take care
|
||||
of that. */
|
||||
}
|
||||
if (var == 0)
|
||||
{
|
||||
var = bind_variable (name, (char *)NULL, 0);
|
||||
if (no_invisible_vars == 0)
|
||||
if (var && no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else if (var->context != 0)
|
||||
|
||||
+58
-12
@@ -1,7 +1,7 @@
|
||||
This file is shopt.def, from which is created shopt.c.
|
||||
It implements the Bash `shopt' builtin.
|
||||
|
||||
Copyright (C) 1994-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -144,6 +144,9 @@ static int shopt_compat43;
|
||||
|
||||
typedef int shopt_set_func_t __P((char *, int));
|
||||
|
||||
/* If you add a new variable name here, make sure to set the default value
|
||||
appropriately in reset_shopt_options. */
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int *value;
|
||||
@@ -304,32 +307,67 @@ shopt_builtin (list)
|
||||
}
|
||||
|
||||
/* Reset the options managed by `shopt' to the values they would have at
|
||||
shell startup. */
|
||||
shell startup. Variables from shopt_vars. */
|
||||
void
|
||||
reset_shopt_options ()
|
||||
{
|
||||
autocd = cdable_vars = cdspelling = 0;
|
||||
check_hashed_filenames = CHECKHASH_DEFAULT;
|
||||
check_window_size = CHECKWINSIZE_DEFAULT;
|
||||
allow_null_glob_expansion = glob_dot_filenames = 0;
|
||||
cdable_vars = mail_warning = 0;
|
||||
no_exit_on_failed_exec = print_shift_error = 0;
|
||||
check_hashed_filenames = cdspelling = expand_aliases = 0;
|
||||
|
||||
no_exit_on_failed_exec = 0;
|
||||
expand_aliases = 0;
|
||||
extended_quote = 1;
|
||||
fail_glob_expansion = 0;
|
||||
glob_asciirange = GLOBASCII_DEFAULT;
|
||||
glob_star = 0;
|
||||
gnu_error_format = 0;
|
||||
hup_on_exit = 0;
|
||||
inherit_errexit = 0;
|
||||
interactive_comments = 1;
|
||||
lastpipe_opt = 0;
|
||||
mail_warning = 0;
|
||||
glob_ignore_case = match_ignore_case = 0;
|
||||
print_shift_error = 0;
|
||||
source_uses_path = promptvars = 1;
|
||||
|
||||
check_window_size = CHECKWINSIZE_DEFAULT;
|
||||
#if defined (JOB_CONTROL)
|
||||
check_jobs_at_exit = 0;
|
||||
#endif
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extended_glob = 0;
|
||||
extended_glob = EXTGLOB_DEFAULT;
|
||||
#endif
|
||||
|
||||
#if defined (HISTORY)
|
||||
literal_history = force_append_history = 0;
|
||||
literal_history = 0;
|
||||
force_append_history = 0;
|
||||
command_oriented_history = 1;
|
||||
#endif
|
||||
|
||||
#if defined (READLINE)
|
||||
complete_fullquote = 1;
|
||||
force_fignore = 1;
|
||||
hist_verify = history_reediting = 0;
|
||||
perform_hostname_completion = 1;
|
||||
# if DIRCOMPLETE_EXPAND_DEFAULT
|
||||
dircomplete_expand = 1;
|
||||
# else
|
||||
dircomplete_expand = 0;
|
||||
#endif
|
||||
dircomplete_spelling = 0;
|
||||
no_empty_command_completion = 0;
|
||||
#endif
|
||||
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
prog_completion_enabled = 1;
|
||||
#endif
|
||||
|
||||
#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
|
||||
xpg_echo = 1;
|
||||
#else
|
||||
xpg_echo = 0;
|
||||
#endif /* DEFAULT_ECHO_TO_XPG */
|
||||
|
||||
shopt_login_shell = login_shell;
|
||||
}
|
||||
@@ -361,6 +399,7 @@ toggle_shopts (mode, list, quiet)
|
||||
{
|
||||
WORD_LIST *l;
|
||||
int ind, rval;
|
||||
SHELL_VAR *v;
|
||||
|
||||
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
||||
{
|
||||
@@ -378,7 +417,9 @@ toggle_shopts (mode, list, quiet)
|
||||
}
|
||||
}
|
||||
|
||||
set_bashopts ();
|
||||
/* Don't set $BASHOPTS here if it hasn't already been initialized */
|
||||
if (v = find_variable ("BASHOPTS"))
|
||||
set_bashopts ();
|
||||
return (rval);
|
||||
}
|
||||
|
||||
@@ -529,7 +570,8 @@ shopt_set_debug_mode (option_name, mode)
|
||||
int mode;
|
||||
{
|
||||
#if defined (DEBUGGER)
|
||||
function_trace_mode = debugging_mode;
|
||||
error_trace_mode = function_trace_mode = debugging_mode;
|
||||
set_shellopts ();
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@@ -768,7 +810,11 @@ parse_bashopts (value)
|
||||
{
|
||||
ind = find_shopt (vname);
|
||||
if (ind >= 0)
|
||||
*shopt_vars[ind].value = 1;
|
||||
{
|
||||
*shopt_vars[ind].value = 1;
|
||||
if (shopt_vars[ind].set_func)
|
||||
(*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1);
|
||||
}
|
||||
free (vname);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ wait_builtin (list)
|
||||
if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
|
||||
{
|
||||
pid = (pid_t)pid_value;
|
||||
status = wait_for_single_pid (pid);
|
||||
status = wait_for_single_pid (pid, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user