b9f7214ef4
Resolves: #1745602
117 lines
4.1 KiB
Diff
117 lines
4.1 KiB
Diff
From 6a3116f58c876ca58a786f0ddff578ecf126588e Mon Sep 17 00:00:00 2001
|
|
From: Chet Ramey <chet.ramey@case.edu>
|
|
Date: Thu, 29 Aug 2019 11:20:15 -0400
|
|
Subject: [PATCH] Bash-5.0 patch 10: changes to posix-mode assignment
|
|
statements preceding functions and special builtins
|
|
|
|
---
|
|
patchlevel.h | 2 +-
|
|
tests/varenv.right | 6 +++---
|
|
variables.c | 38 ++++++++++++++++++++++++++------------
|
|
3 files changed, 30 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/patchlevel.h b/patchlevel.h
|
|
index 02f1d606..8002af70 100644
|
|
--- a/patchlevel.h
|
|
+++ b/patchlevel.h
|
|
@@ -25,6 +25,6 @@
|
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
|
looks for to find the patch level (for the sccs version string). */
|
|
|
|
-#define PATCHLEVEL 9
|
|
+#define PATCHLEVEL 10
|
|
|
|
#endif /* _PATCHLEVEL_H_ */
|
|
diff --git a/tests/varenv.right b/tests/varenv.right
|
|
index 159a8773..ca7d4cf1 100644
|
|
--- a/tests/varenv.right
|
|
+++ b/tests/varenv.right
|
|
@@ -146,9 +146,9 @@ declare -x foo="abc"
|
|
inside: declare -x var="value"
|
|
outside: declare -- var="one"
|
|
inside: declare -x var="value"
|
|
-outside: declare -x var="value"
|
|
-inside: declare -- var="local"
|
|
-outside: declare -x var="global"
|
|
+outside: declare -- var="outside"
|
|
+inside: declare -x var="global"
|
|
+outside: declare -- var="outside"
|
|
foo=<unset> environment foo=
|
|
foo=foo environment foo=foo
|
|
foo=foo environment foo=foo
|
|
diff --git a/variables.c b/variables.c
|
|
index 610629ab..af3fd04a 100644
|
|
--- a/variables.c
|
|
+++ b/variables.c
|
|
@@ -4460,9 +4460,9 @@ char **tempvar_list;
|
|
int tvlist_ind;
|
|
|
|
/* Take a variable from an assignment statement preceding a posix special
|
|
- builtin (including `return') and create a global variable from it. This
|
|
- is called from merge_temporary_env, which is only called when in posix
|
|
- mode. */
|
|
+ builtin (including `return') and create a variable from it as if a
|
|
+ standalone assignment statement had been performed. This is called from
|
|
+ merge_temporary_env, which is only called when in posix mode. */
|
|
static void
|
|
push_posix_temp_var (data)
|
|
PTR_T data;
|
|
@@ -4472,16 +4472,27 @@ push_posix_temp_var (data)
|
|
|
|
var = (SHELL_VAR *)data;
|
|
|
|
- binding_table = global_variables->table;
|
|
- if (binding_table == 0)
|
|
- binding_table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
|
|
+ /* Just like do_assignment_internal(). This makes assignments preceding
|
|
+ special builtins act like standalone assignment statements when in
|
|
+ posix mode, satisfying the posix requirement that this affect the
|
|
+ "current execution environment." */
|
|
+ v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP);
|
|
|
|
- v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
|
|
+ /* If this modifies an existing local variable, v->context will be non-zero.
|
|
+ If it comes back with v->context == 0, we bound at the global context.
|
|
+ Set binding_table appropriately. It doesn't matter whether it's correct
|
|
+ if the variable is local, only that it's not global_variables->table */
|
|
+ binding_table = v->context ? shell_variables->table : global_variables->table;
|
|
|
|
/* global variables are no longer temporary and don't need propagating. */
|
|
- var->attributes &= ~(att_tempvar|att_propagate);
|
|
+ if (binding_table == global_variables->table)
|
|
+ var->attributes &= ~(att_tempvar|att_propagate);
|
|
+
|
|
if (v)
|
|
- v->attributes |= var->attributes;
|
|
+ {
|
|
+ v->attributes |= var->attributes;
|
|
+ v->attributes &= ~att_tempvar; /* not a temp var now */
|
|
+ }
|
|
|
|
if (find_special_var (var->name) >= 0)
|
|
tempvar_list[tvlist_ind++] = savestring (var->name);
|
|
@@ -4575,14 +4586,17 @@ dispose_temporary_env (pushf)
|
|
sh_free_func_t *pushf;
|
|
{
|
|
int i;
|
|
+ HASH_TABLE *disposer;
|
|
|
|
tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
|
|
tempvar_list[tvlist_ind = 0] = 0;
|
|
-
|
|
- hash_flush (temporary_env, pushf);
|
|
- hash_dispose (temporary_env);
|
|
+
|
|
+ disposer = temporary_env;
|
|
temporary_env = (HASH_TABLE *)NULL;
|
|
|
|
+ hash_flush (disposer, pushf);
|
|
+ hash_dispose (disposer);
|
|
+
|
|
tempvar_list[tvlist_ind] = 0;
|
|
|
|
array_needs_making = 1;
|
|
--
|
|
2.21.0
|
|
|