aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-05-05 15:14:10 +0100
committerRon Yorston <rmy@pobox.com>2022-05-05 15:14:10 +0100
commit3b5042430fc4b82d44e0430f9ecc21a9228d1651 (patch)
tree192bbe0db34239cbc927ddeece00162584bca2d4
parent9e535b09a70a1ef7a2260e6d6955f7bbf291a08f (diff)
downloadbusybox-w32-3b5042430fc4b82d44e0430f9ecc21a9228d1651.tar.gz
busybox-w32-3b5042430fc4b82d44e0430f9ecc21a9228d1651.tar.bz2
busybox-w32-3b5042430fc4b82d44e0430f9ecc21a9228d1651.zip
win32: better fix for empty environment variables
It appears the CRT and OS each have a copy of the environment. mingw_putenv() fools the CRT into accepting an empty environment variable by calling _putenv("V=0") then truncating the new value by hand. But _putenv() also updates the OS environment with the fake 'V=0' value. Commit 5b48ca53b (win32: pass NULL to spawnve, not environ) resulted in this fake value being used and hence empty variables getting the value '0'. - Add a call to SetEnvironmentVariable() in mingw_putenv() to update the OS environment. - Restore the use of NULL environment pointers in mingw_spawnvp(). - Add a test. (GitHub issue #250)
-rwxr-xr-xtestsuite/env.tests67
-rw-r--r--win32/env.c4
-rw-r--r--win32/process.c13
3 files changed, 75 insertions, 9 deletions
diff --git a/testsuite/env.tests b/testsuite/env.tests
new file mode 100755
index 000000000..456808728
--- /dev/null
+++ b/testsuite/env.tests
@@ -0,0 +1,67 @@
1#!/bin/sh
2# Copyright 2022 by Ron Yorston
3# Licensed under GPLv2, see file LICENSE in this source tree.
4
5. ./testing.sh
6
7# testing "test name" "commands" "expected result" "file input" "stdin"
8
9# Not so much a test of 'env' as of whether environment variables
10# (or the lack thereof) are correctly passed to child processes.
11testing "environment variables 1a" \
12 "V=set env sh -c 'env | grep ^V='" \
13 "V=set
14" "" ""
15
16testing "environment variables 1b" \
17 "V= env sh -c 'env | grep ^V='" \
18 "V=
19" "" ""
20
21testing "environment variables 1c" \
22 "env sh -c 'env | grep ^V='" \
23 "" "" ""
24
25testing "environment variables 2a" \
26 "V=set sh -c 'env | grep ^V='" \
27 "V=set
28" "" ""
29
30testing "environment variables 2b" \
31 "V= sh -c 'env | grep ^V='" \
32 "V=
33" "" ""
34
35testing "environment variables 2c" \
36 "sh -c 'env | grep ^V='" \
37 "" "" ""
38
39testing "environment variables 3a" \
40 "V=set env sh -c 'echo \${V-unset}'" \
41 "set
42" "" ""
43
44testing "environment variables 3b" \
45 "V= env sh -c 'echo \${V-unset}'" \
46 "
47" "" ""
48
49testing "environment variables 3c" \
50 "env sh -c 'echo \${V-unset}'" \
51 "unset
52" "" ""
53
54testing "environment variables 4a" \
55 "V=set sh -c 'echo \${V-unset}'" \
56 "set
57" "" ""
58
59testing "environment variables 4b" \
60 "V= sh -c 'echo \${V-unset}'" \
61 "
62" "" ""
63
64testing "environment variables 4c" \
65 "sh -c 'echo \${V-unset}'" \
66 "unset
67" "" ""
diff --git a/win32/env.c b/win32/env.c
index 4d4e9c8fd..8e54c4c5e 100644
--- a/win32/env.c
+++ b/win32/env.c
@@ -100,6 +100,10 @@ int mingw_putenv(const char *env)
100 break; 100 break;
101 } 101 }
102 } 102 }
103
104 /* tell the OS environment about the change */
105 envstr[s - env] = '\0';
106 SetEnvironmentVariable(envstr, "");
103 free(envstr); 107 free(envstr);
104 } 108 }
105 109
diff --git a/win32/process.c b/win32/process.c
index 5978226f0..d4ab07ad8 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -345,32 +345,27 @@ mingw_spawnvp(int mode, const char *cmd, char *const *argv)
345{ 345{
346 char *prog; 346 char *prog;
347 intptr_t ret; 347 intptr_t ret;
348#if !defined(_UCRT)
349 char *const *envp = environ;
350#else
351 char *const *envp = NULL;
352#endif
353 348
354#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 349#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1
355 if (find_applet_by_name(cmd) >= 0) 350 if (find_applet_by_name(cmd) >= 0)
356 return mingw_spawn_applet(mode, argv, envp); 351 return mingw_spawn_applet(mode, argv, NULL);
357 else 352 else
358#endif 353#endif
359 if (has_path(cmd)) { 354 if (has_path(cmd)) {
360 char *path = alloc_system_drive(cmd); 355 char *path = alloc_system_drive(cmd);
361 add_win32_extension(path); 356 add_win32_extension(path);
362 ret = mingw_spawn_interpreter(mode, path, argv, envp, 0); 357 ret = mingw_spawn_interpreter(mode, path, argv, NULL, 0);
363 free(path); 358 free(path);
364#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 359#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1
365 if (ret == -1 && unix_path(cmd) && 360 if (ret == -1 && unix_path(cmd) &&
366 find_applet_by_name(bb_basename(cmd)) >= 0) { 361 find_applet_by_name(bb_basename(cmd)) >= 0) {
367 return mingw_spawn_applet(mode, argv, envp); 362 return mingw_spawn_applet(mode, argv, NULL);
368 } 363 }
369#endif 364#endif
370 return ret; 365 return ret;
371 } 366 }
372 else if ((prog=find_first_executable(cmd)) != NULL) { 367 else if ((prog=find_first_executable(cmd)) != NULL) {
373 ret = mingw_spawn_interpreter(mode, prog, argv, envp, 0); 368 ret = mingw_spawn_interpreter(mode, prog, argv, NULL, 0);
374 free(prog); 369 free(prog);
375 return ret; 370 return ret;
376 } 371 }