From db03ff5ea8ce258da4399cb26924e34916dc83f7 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 14 Jan 2014 21:12:21 +0000 Subject: ash: reset pointers to builtin environment variables after fork The builtin environment variables can be accessed using macros that reference the varinit array. initvar puts pointers to varinit into the variable hash table. During forkshell_prepare two copies of the builtin variables are made: once as the varinit array and again through the pointers in the hash table. One of these copies is accessed by code that uses the macros and the other by code that looks up the variable by name. This is the cause of the strange behaviour of IFS in backticks: https://github.com/pclouds/busybox-w32/issues/12 To avoid the problem the pointers in the hash table are reset to the varinit array in forkshell_init. It seemed easier to do it this way than to try and prevent the duplicate copies being made in the first place. --- shell/ash.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 6b7c9f2a2..40660dad5 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -13937,6 +13937,30 @@ int ash_main(int argc UNUSED_PARAM, char **argv) } #if ENABLE_PLATFORM_MINGW32 +/* + * Reset the pointers to the builtin environment variables in the hash + * table to point to varinit rather than the bogus copy created during + * forkshell_prepare. + */ +static void +reinitvar(void) +{ + struct var *vp; + struct var *end; + struct var **vpp; + struct var **old; + + vp = varinit; + end = vp + ARRAY_SIZE(varinit); + do { + vpp = hashvar(vp->var_text); + if ( (old=findvar(vpp, vp->var_text)) != NULL ) { + vp->next = (*old)->next; + *old = vp; + } + } while (++vp < end); +} + /* FIXME: should consider running forkparent() and forkchild() */ static int spawn_forkshell(struct job *jp, struct forkshell *fs, int mode) @@ -14424,6 +14448,8 @@ forkshell_init(const char *idstr) *gmpp = fs->gmp; cmdtable = fs->cmdtable; + reinitvar(); + fs->fp(fs); } -- cgit v1.2.3-55-g6feb