diff options
author | millert <> | 2009-06-03 15:52:16 +0000 |
---|---|---|
committer | millert <> | 2009-06-03 15:52:16 +0000 |
commit | ba53e391e204926a7a71b5a9848b928a56af0062 (patch) | |
tree | 27076f4f89f7c81fc3ad7e7b02facdf369d4b2e6 /src/lib/libc/stdlib/setenv.c | |
parent | 43170abfbd0c2858c372e7ef19f5dffe4f34137c (diff) | |
download | openbsd-ba53e391e204926a7a71b5a9848b928a56af0062.tar.gz openbsd-ba53e391e204926a7a71b5a9848b928a56af0062.tar.bz2 openbsd-ba53e391e204926a7a71b5a9848b928a56af0062.zip |
Make putenv(), setenv() and unsetenv() standards compliant. The
standard explicitly disallows passing setenv a name with a '=' in
it but historic BSD behavior is to allow this but to ignore the '='
and anything after it.
Diffstat (limited to 'src/lib/libc/stdlib/setenv.c')
-rw-r--r-- | src/lib/libc/stdlib/setenv.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c index 36540ebb0c..242830d7b9 100644 --- a/src/lib/libc/stdlib/setenv.c +++ b/src/lib/libc/stdlib/setenv.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: setenv.c,v 1.9 2005/08/08 08:05:37 espie Exp $ */ | 1 | /* $OpenBSD: setenv.c,v 1.10 2009/06/03 15:52:16 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1987 Regents of the University of California. | 3 | * Copyright (c) 1987 Regents of the University of California. |
4 | * All rights reserved. | 4 | * All rights reserved. |
@@ -28,12 +28,53 @@ | |||
28 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <errno.h> | ||
31 | #include <stdlib.h> | 32 | #include <stdlib.h> |
32 | #include <string.h> | 33 | #include <string.h> |
33 | 34 | ||
34 | char *__findenv(const char *name, int *offset); | 35 | char *__findenv(const char *name, int len, int *offset); |
35 | 36 | ||
36 | extern char **environ; | 37 | extern char **environ; |
38 | static char **lastenv; /* last value of environ */ | ||
39 | |||
40 | /* | ||
41 | * putenv -- | ||
42 | * Add a name=value string directly to the environmental, replacing | ||
43 | * any current value. | ||
44 | */ | ||
45 | int | ||
46 | putenv(char *str) | ||
47 | { | ||
48 | char **P, *cp; | ||
49 | size_t cnt; | ||
50 | int offset; | ||
51 | |||
52 | for (cp = str; *cp && *cp != '='; ++cp) | ||
53 | ; | ||
54 | if (*cp != '=') { | ||
55 | errno = EINVAL; | ||
56 | return (-1); /* missing `=' in string */ | ||
57 | } | ||
58 | |||
59 | if (__findenv(str, (int)(cp - str), &offset) != NULL) { | ||
60 | environ[offset] = str; | ||
61 | return (0); | ||
62 | } | ||
63 | |||
64 | /* create new slot for string */ | ||
65 | for (P = environ; *P != NULL; P++) | ||
66 | ; | ||
67 | cnt = P - environ; | ||
68 | P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); | ||
69 | if (!P) | ||
70 | return (-1); | ||
71 | if (lastenv != environ) | ||
72 | memcpy(P, environ, cnt * sizeof(char *)); | ||
73 | lastenv = environ = P; | ||
74 | environ[cnt] = str; | ||
75 | environ[cnt + 1] = NULL; | ||
76 | return (0); | ||
77 | } | ||
37 | 78 | ||
38 | /* | 79 | /* |
39 | * setenv -- | 80 | * setenv -- |
@@ -43,14 +84,21 @@ extern char **environ; | |||
43 | int | 84 | int |
44 | setenv(const char *name, const char *value, int rewrite) | 85 | setenv(const char *name, const char *value, int rewrite) |
45 | { | 86 | { |
46 | static char **lastenv; /* last value of environ */ | ||
47 | char *C; | 87 | char *C; |
88 | const char *np; | ||
48 | int l_value, offset; | 89 | int l_value, offset; |
49 | 90 | ||
50 | if (*value == '=') /* no `=' in value */ | 91 | for (np = name; *np && *np != '='; ++np) |
51 | ++value; | 92 | ; |
93 | #ifdef notyet | ||
94 | if (*np) { | ||
95 | errno = EINVAL; | ||
96 | return (-1); /* has `=' in name */ | ||
97 | } | ||
98 | #endif | ||
99 | |||
52 | l_value = strlen(value); | 100 | l_value = strlen(value); |
53 | if ((C = __findenv(name, &offset))) { /* find if already exists */ | 101 | if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { |
54 | if (!rewrite) | 102 | if (!rewrite) |
55 | return (0); | 103 | return (0); |
56 | if (strlen(C) >= l_value) { /* old larger; copy over */ | 104 | if (strlen(C) >= l_value) { /* old larger; copy over */ |
@@ -74,10 +122,8 @@ setenv(const char *name, const char *value, int rewrite) | |||
74 | offset = cnt; | 122 | offset = cnt; |
75 | environ[cnt + 1] = NULL; | 123 | environ[cnt + 1] = NULL; |
76 | } | 124 | } |
77 | for (C = (char *)name; *C && *C != '='; ++C) | ||
78 | ; /* no `=' in name */ | ||
79 | if (!(environ[offset] = /* name + `=' + value */ | 125 | if (!(environ[offset] = /* name + `=' + value */ |
80 | malloc((size_t)((int)(C - name) + l_value + 2)))) | 126 | malloc((size_t)((int)(np - name) + l_value + 2)))) |
81 | return (-1); | 127 | return (-1); |
82 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) | 128 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) |
83 | ; | 129 | ; |
@@ -90,14 +136,25 @@ setenv(const char *name, const char *value, int rewrite) | |||
90 | * unsetenv(name) -- | 136 | * unsetenv(name) -- |
91 | * Delete environmental variable "name". | 137 | * Delete environmental variable "name". |
92 | */ | 138 | */ |
93 | void | 139 | int |
94 | unsetenv(const char *name) | 140 | unsetenv(const char *name) |
95 | { | 141 | { |
96 | char **P; | 142 | char **P; |
143 | const char *np; | ||
97 | int offset; | 144 | int offset; |
98 | 145 | ||
99 | while (__findenv(name, &offset)) /* if set multiple times */ | 146 | for (np = name; *np && *np != '='; ++np) |
147 | ; | ||
148 | if (*np) { | ||
149 | errno = EINVAL; | ||
150 | return (-1); /* has `=' in name */ | ||
151 | } | ||
152 | |||
153 | /* could be set multiple times */ | ||
154 | while (__findenv(name, (int)(np - name), &offset)) { | ||
100 | for (P = &environ[offset];; ++P) | 155 | for (P = &environ[offset];; ++P) |
101 | if (!(*P = *(P + 1))) | 156 | if (!(*P = *(P + 1))) |
102 | break; | 157 | break; |
158 | } | ||
159 | return (0); | ||
103 | } | 160 | } |