diff options
Diffstat (limited to '')
-rw-r--r-- | win32/env.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/win32/env.c b/win32/env.c new file mode 100644 index 000000000..f30ee62f6 --- /dev/null +++ b/win32/env.c | |||
@@ -0,0 +1,117 @@ | |||
1 | #include "libbb.h" | ||
2 | |||
3 | #undef getenv | ||
4 | #undef putenv | ||
5 | |||
6 | char *mingw_getenv(const char *name) | ||
7 | { | ||
8 | char *result = getenv(name); | ||
9 | if (!result) { | ||
10 | if (!strcmp(name, "TMPDIR")) { | ||
11 | /* on Windows it is TMP and TEMP */ | ||
12 | result = getenv("TMP"); | ||
13 | if (!result) | ||
14 | result = getenv("TEMP"); | ||
15 | } else if (!strcmp(name, "HOME")) { | ||
16 | struct passwd *p = getpwuid(getuid()); | ||
17 | if (p) | ||
18 | result = p->pw_dir; | ||
19 | } | ||
20 | } | ||
21 | return result; | ||
22 | } | ||
23 | |||
24 | int setenv(const char *name, const char *value, int replace) | ||
25 | { | ||
26 | int out; | ||
27 | char *envstr; | ||
28 | |||
29 | if (!name || !*name || strchr(name, '=') || !value) return -1; | ||
30 | if (!replace) { | ||
31 | if (getenv(name)) return 0; | ||
32 | } | ||
33 | |||
34 | envstr = xasprintf("%s=%s", name, value); | ||
35 | out = mingw_putenv(envstr); | ||
36 | free(envstr); | ||
37 | |||
38 | return out; | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Removing an environment variable with WIN32 _putenv requires an argument | ||
43 | * like "NAME="; glibc omits the '='. The implementations of unsetenv and | ||
44 | * clearenv allow for this. | ||
45 | * | ||
46 | * It isn't possible to create an environment variable with an empty value | ||
47 | * using WIN32 _putenv. | ||
48 | */ | ||
49 | int unsetenv(const char *name) | ||
50 | { | ||
51 | char *envstr; | ||
52 | int ret; | ||
53 | |||
54 | if (!name || !*name || strchr(name, '=') ) { | ||
55 | return -1; | ||
56 | } | ||
57 | |||
58 | envstr = xasprintf("%s=", name); | ||
59 | ret = _putenv(envstr); | ||
60 | free(envstr); | ||
61 | |||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | int clearenv(void) | ||
66 | { | ||
67 | char *envp, *name, *s; | ||
68 | |||
69 | while ( environ && (envp=*environ) ) { | ||
70 | if ( (s=strchr(envp, '=')) != NULL ) { | ||
71 | name = xstrndup(envp, s-envp+1); | ||
72 | if (_putenv(name) == -1) { | ||
73 | free(name); | ||
74 | return -1; | ||
75 | } | ||
76 | free(name); | ||
77 | } | ||
78 | else { | ||
79 | return -1; | ||
80 | } | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int mingw_putenv(const char *env) | ||
86 | { | ||
87 | char *s, **envp; | ||
88 | int ret = 0; | ||
89 | |||
90 | if ( (s=strchr(env, '=')) == NULL ) { | ||
91 | return unsetenv(env); | ||
92 | } | ||
93 | |||
94 | if (s[1] != '\0') { | ||
95 | /* setting non-empty value is fine */ | ||
96 | return _putenv(env); | ||
97 | } | ||
98 | else { | ||
99 | /* set empty value by setting a non-empty one then truncating */ | ||
100 | char *envstr = xasprintf("%s0", env); | ||
101 | ret = _putenv(envstr); | ||
102 | |||
103 | for (envp = environ; *envp; ++envp) { | ||
104 | if (strcmp(*envp, envstr) == 0) { | ||
105 | (*envp)[s - env + 1] = '\0'; | ||
106 | break; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* tell the OS environment about the change */ | ||
111 | envstr[s - env] = '\0'; | ||
112 | SetEnvironmentVariable(envstr, ""); | ||
113 | free(envstr); | ||
114 | } | ||
115 | |||
116 | return ret; | ||
117 | } | ||