summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/setenv.c
diff options
context:
space:
mode:
authormillert <>2009-06-03 15:52:16 +0000
committermillert <>2009-06-03 15:52:16 +0000
commitba53e391e204926a7a71b5a9848b928a56af0062 (patch)
tree27076f4f89f7c81fc3ad7e7b02facdf369d4b2e6 /src/lib/libc/stdlib/setenv.c
parent43170abfbd0c2858c372e7ef19f5dffe4f34137c (diff)
downloadopenbsd-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.c79
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
34char *__findenv(const char *name, int *offset); 35char *__findenv(const char *name, int len, int *offset);
35 36
36extern char **environ; 37extern char **environ;
38static 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 */
45int
46putenv(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;
43int 84int
44setenv(const char *name, const char *value, int rewrite) 85setenv(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 */
93void 139int
94unsetenv(const char *name) 140unsetenv(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}