mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-05 17:52:30 +02:00
Bash-4.2 distribution sources and documentation
This commit is contained in:
+125
-22
@@ -1,6 +1,6 @@
|
||||
/* variables.c -- Functions for hacking shell variables. */
|
||||
|
||||
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -83,7 +83,7 @@ extern char **environ;
|
||||
|
||||
/* Variables used here and defined in other files. */
|
||||
extern int posixly_correct;
|
||||
extern int line_number;
|
||||
extern int line_number, line_number_base;
|
||||
extern int subshell_environment, indirection_level, subshell_level;
|
||||
extern int build_version, patch_level;
|
||||
extern int expanding_redir;
|
||||
@@ -99,6 +99,7 @@ extern char *command_execution_string;
|
||||
extern time_t shell_start_time;
|
||||
extern int assigning_in_environment;
|
||||
extern int executing_builtin;
|
||||
extern int funcnest_max;
|
||||
|
||||
#if defined (READLINE)
|
||||
extern int no_line_editing;
|
||||
@@ -158,7 +159,6 @@ static int export_env_size;
|
||||
|
||||
#if defined (READLINE)
|
||||
static int winsize_assignment; /* currently assigning to LINES or COLUMNS */
|
||||
static int winsize_assigned; /* assigned to LINES or COLUMNS */
|
||||
#endif
|
||||
|
||||
/* Some forward declarations. */
|
||||
@@ -387,11 +387,14 @@ initialize_shell_variables (env, privmode)
|
||||
#endif
|
||||
{
|
||||
temp_var = bind_variable (name, string, 0);
|
||||
if (legal_identifier (name))
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
else
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
array_needs_making = 1;
|
||||
if (temp_var)
|
||||
{
|
||||
if (legal_identifier (name))
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
else
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
array_needs_making = 1;
|
||||
}
|
||||
}
|
||||
|
||||
name[char_index] = '=';
|
||||
@@ -588,6 +591,10 @@ initialize_shell_variables (env, privmode)
|
||||
/* Get the user's real and effective user ids. */
|
||||
uidset ();
|
||||
|
||||
temp_var = find_variable ("BASH_XTRACEFD");
|
||||
if (temp_var && imported_p (temp_var))
|
||||
sv_xtracefd (temp_var->name);
|
||||
|
||||
/* Initialize the dynamic variables, and seed their values. */
|
||||
initialize_dynamic_variables ();
|
||||
}
|
||||
@@ -1228,17 +1235,14 @@ static int seeded_subshell = 0;
|
||||
static int
|
||||
brand ()
|
||||
{
|
||||
#if 0
|
||||
rseed = rseed * 1103515245 + 12345;
|
||||
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
|
||||
#else
|
||||
/* From "Random number generators: good ones are hard to find",
|
||||
Park and Miller, Communications of the ACM, vol. 31, no. 10,
|
||||
October 1988, p. 1195. filtered through FreeBSD */
|
||||
long h, l;
|
||||
|
||||
/* Can't seed with 0. */
|
||||
if (rseed == 0)
|
||||
seedrand ();
|
||||
rseed = 123459876;
|
||||
h = rseed / 127773;
|
||||
l = rseed % 127773;
|
||||
rseed = 16807 * l - 2836 * h;
|
||||
@@ -1247,7 +1251,6 @@ brand ()
|
||||
rseed += 0x7fffffff;
|
||||
#endif
|
||||
return ((unsigned int)(rseed & 32767)); /* was % 32768 */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the random number generator seed to SEED. */
|
||||
@@ -1329,7 +1332,7 @@ assign_lineno (var, value, unused, key)
|
||||
|
||||
if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
|
||||
new_value = 0;
|
||||
line_number = new_value;
|
||||
line_number = line_number_base = new_value;
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -1791,6 +1794,20 @@ find_variable_internal (name, force_tempenv)
|
||||
return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
find_global_variable (name)
|
||||
const char *name;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
var = var_lookup (name, global_variables);
|
||||
|
||||
if (var == 0)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
|
||||
return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var);
|
||||
}
|
||||
|
||||
/* Look up the variable entry named NAME. Returns the entry or NULL. */
|
||||
SHELL_VAR *
|
||||
find_variable (name)
|
||||
@@ -2371,7 +2388,7 @@ bind_int_variable (lhs, rhs)
|
||||
#endif
|
||||
v = bind_variable (lhs, rhs, 0);
|
||||
|
||||
if (isint)
|
||||
if (v && isint)
|
||||
VSETATTR (v, att_integer);
|
||||
|
||||
return (v);
|
||||
@@ -2470,8 +2487,9 @@ bind_function_def (name, value)
|
||||
responsible for moving the main temporary env to one of the other
|
||||
temporary environments. The expansion code in subst.c calls this. */
|
||||
int
|
||||
assign_in_env (word)
|
||||
assign_in_env (word, flags)
|
||||
WORD_DESC *word;
|
||||
int flags;
|
||||
{
|
||||
int offset;
|
||||
char *name, *temp, *value;
|
||||
@@ -2529,8 +2547,13 @@ assign_in_env (word)
|
||||
|
||||
array_needs_making = 1;
|
||||
|
||||
#if 0
|
||||
if (ifsname (name))
|
||||
setifs (var);
|
||||
else
|
||||
#endif
|
||||
if (flags)
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
if (echo_command_at_execute)
|
||||
/* The Korn shell prints the `+ ' in front of assignment statements,
|
||||
@@ -2820,7 +2843,7 @@ delete_all_variables (hashed_vars)
|
||||
if (!entry) \
|
||||
{ \
|
||||
entry = bind_variable (name, "", 0); \
|
||||
if (!no_invisible_vars) entry->attributes |= att_invisible; \
|
||||
if (!no_invisible_vars && entry) entry->attributes |= att_invisible; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
@@ -3250,6 +3273,9 @@ find_tempenv_variable (name)
|
||||
return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL);
|
||||
}
|
||||
|
||||
char **tempvar_list;
|
||||
int tvlist_ind;
|
||||
|
||||
/* Push the variable described by (SHELL_VAR *)DATA down to the next
|
||||
variable context from the temporary environment. */
|
||||
static void
|
||||
@@ -3285,6 +3311,9 @@ push_temp_var (data)
|
||||
}
|
||||
v->attributes |= var->attributes;
|
||||
|
||||
if (find_special_var (var->name) >= 0)
|
||||
tempvar_list[tvlist_ind++] = savestring (var->name);
|
||||
|
||||
dispose_variable (var);
|
||||
}
|
||||
|
||||
@@ -3298,24 +3327,46 @@ propagate_temp_var (data)
|
||||
if (tempvar_p (var) && (var->attributes & att_propagate))
|
||||
push_temp_var (data);
|
||||
else
|
||||
dispose_variable (var);
|
||||
{
|
||||
if (find_special_var (var->name) >= 0)
|
||||
tempvar_list[tvlist_ind++] = savestring (var->name);
|
||||
dispose_variable (var);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the storage used in the hash table for temporary
|
||||
environment variables. PUSHF is a function to be called
|
||||
to free each hash table entry. It takes care of pushing variables
|
||||
to previous scopes if appropriate. */
|
||||
to previous scopes if appropriate. PUSHF stores names of variables
|
||||
that require special handling (e.g., IFS) on tempvar_list, so this
|
||||
function can call stupidly_hack_special_variables on all the
|
||||
variables in the list when the temporary hash table is destroyed. */
|
||||
static void
|
||||
dispose_temporary_env (pushf)
|
||||
sh_free_func_t *pushf;
|
||||
{
|
||||
int i;
|
||||
|
||||
tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
|
||||
tempvar_list[tvlist_ind = 0] = 0;
|
||||
|
||||
hash_flush (temporary_env, pushf);
|
||||
hash_dispose (temporary_env);
|
||||
temporary_env = (HASH_TABLE *)NULL;
|
||||
|
||||
tempvar_list[tvlist_ind] = 0;
|
||||
|
||||
array_needs_making = 1;
|
||||
|
||||
sv_ifs ("IFS"); /* XXX here for now */
|
||||
#if 0
|
||||
sv_ifs ("IFS"); /* XXX here for now -- check setifs in assign_in_env */
|
||||
#endif
|
||||
for (i = 0; i < tvlist_ind; i++)
|
||||
stupidly_hack_special_variables (tempvar_list[i]);
|
||||
|
||||
strvec_dispose (tempvar_list);
|
||||
tempvar_list = 0;
|
||||
tvlist_ind = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4109,6 +4160,8 @@ static struct name_and_function special_vars[] = {
|
||||
{ "COMP_WORDBREAKS", sv_comp_wordbreaks },
|
||||
#endif
|
||||
|
||||
{ "FUNCNEST", sv_funcnest },
|
||||
|
||||
{ "GLOBIGNORE", sv_globignore },
|
||||
|
||||
#if defined (HISTORY)
|
||||
@@ -4280,6 +4333,22 @@ sv_mail (name)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sv_funcnest (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
intmax_t num;
|
||||
|
||||
v = find_variable (name);
|
||||
if (v == 0)
|
||||
funcnest_max = 0;
|
||||
else if (legal_number (value_cell (v), &num) == 0)
|
||||
funcnest_max = 0;
|
||||
else
|
||||
funcnest_max = num;
|
||||
}
|
||||
|
||||
/* What to do when GLOBIGNORE changes. */
|
||||
void
|
||||
sv_globignore (name)
|
||||
@@ -4347,7 +4416,7 @@ sv_winsize (name)
|
||||
{
|
||||
if (legal_number (value_cell (v), &xd) == 0)
|
||||
return;
|
||||
winsize_assignment = winsize_assigned = 1;
|
||||
winsize_assignment = 1;
|
||||
d = xd; /* truncate */
|
||||
if (name[0] == 'L') /* LINES */
|
||||
rl_set_screen_size (d, -1);
|
||||
@@ -4640,6 +4709,40 @@ set_pipestatus_array (ps, nproc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ARRAY *
|
||||
save_pipestatus_array ()
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
ARRAY *a, *a2;
|
||||
|
||||
v = find_variable ("PIPESTATUS");
|
||||
if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
|
||||
return ((ARRAY *)NULL);
|
||||
|
||||
a = array_cell (v);
|
||||
a2 = array_copy (array_cell (v));
|
||||
|
||||
return a2;
|
||||
}
|
||||
|
||||
void
|
||||
restore_pipestatus_array (a)
|
||||
ARRAY *a;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
ARRAY *a2;
|
||||
|
||||
v = find_variable ("PIPESTATUS");
|
||||
/* XXX - should we still assign even if existing value is NULL? */
|
||||
if (v == 0 || array_p (v) == 0 || array_cell (v) == 0)
|
||||
return;
|
||||
|
||||
a2 = array_cell (v);
|
||||
var_setarray (v, a);
|
||||
|
||||
array_dispose (a2);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user