summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/setenv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/setenv.c')
-rw-r--r--src/lib/libc/stdlib/setenv.c166
1 files changed, 113 insertions, 53 deletions
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..9060fdba88 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: setenv.c,v 1.14 2012/09/23 16:08:04 jeremy Exp $ */
1/* 2/*
2 * Copyright (c) 1987 Regents of the University of California. 3 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 14 * 3. Neither the name of the University nor the names of its contributors
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,71 +28,122 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <errno.h>
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/
36static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 32#include <stdlib.h>
40#include <string.h> 33#include <string.h>
41 34
35char *__findenv(const char *name, int len, int *offset);
36
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 = 0;
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 /* could be set multiple times */
62 while (__findenv(str, (int)(cp - str), &offset)) {
63 for (P = &environ[offset];; ++P)
64 if (!(*P = *(P + 1)))
65 break;
66 }
67 return (0);
68 }
69
70 /* create new slot for string */
71 for (P = environ; *P != NULL; P++)
72 ;
73 cnt = P - environ;
74 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
75 if (!P)
76 return (-1);
77 if (lastenv != environ)
78 memcpy(P, environ, cnt * sizeof(char *));
79 lastenv = environ = P;
80 environ[cnt] = str;
81 environ[cnt + 1] = NULL;
82 return (0);
83}
84
42/* 85/*
43 * setenv -- 86 * setenv --
44 * Set the value of the environmental variable "name" to be 87 * Set the value of the environmental variable "name" to be
45 * "value". If rewrite is set, replace any current value. 88 * "value". If rewrite is set, replace any current value.
46 */ 89 */
47int 90int
48setenv(name, value, rewrite) 91setenv(const char *name, const char *value, int rewrite)
49 register const char *name;
50 register const char *value;
51 int rewrite;
52{ 92{
53 extern char **environ; 93 char *C, **P;
54 static int alloced; /* if allocated space before */ 94 const char *np;
55 register char *C; 95 int l_value, offset = 0;
56 int l_value, offset; 96
57 char *__findenv(); 97 if (!name || !*name) {
98 errno = EINVAL;
99 return (-1);
100 }
101 for (np = name; *np && *np != '='; ++np)
102 ;
103 if (*np) {
104 errno = EINVAL;
105 return (-1); /* has `=' in name */
106 }
58 107
59 if (*value == '=') /* no `=' in value */
60 ++value;
61 l_value = strlen(value); 108 l_value = strlen(value);
62 if ((C = __findenv(name, &offset))) { /* find if already exists */ 109 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
110 int tmpoff = offset + 1;
63 if (!rewrite) 111 if (!rewrite)
64 return (0); 112 return (0);
113#if 0 /* XXX - existing entry may not be writable */
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 114 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 115 while ((*C++ = *value++))
116 ;
67 return (0); 117 return (0);
68 } 118 }
119#endif
120 /* could be set multiple times */
121 while (__findenv(name, (int)(np - name), &tmpoff)) {
122 for (P = &environ[tmpoff];; ++P)
123 if (!(*P = *(P + 1)))
124 break;
125 }
69 } else { /* create new slot */ 126 } else { /* create new slot */
70 register int cnt; 127 size_t cnt;
71 register char **P;
72 128
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 129 for (P = environ; *P != NULL; P++)
74 if (alloced) { /* just increase size */ 130 ;
75 environ = (char **)realloc((char *)environ, 131 cnt = P - environ;
76 (size_t)(sizeof(char *) * (cnt + 2))); 132 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
77 if (!environ) 133 if (!P)
78 return (-1); 134 return (-1);
79 } 135 if (lastenv != environ)
80 else { /* get new space */ 136 memcpy(P, environ, cnt * sizeof(char *));
81 alloced = 1; /* copy old entries into it */ 137 lastenv = environ = P;
82 P = (char **)malloc((size_t)(sizeof(char *) *
83 (cnt + 2)));
84 if (!P)
85 return (-1);
86 bcopy(environ, P, cnt * sizeof(char *));
87 environ = P;
88 }
89 environ[cnt + 1] = NULL;
90 offset = cnt; 138 offset = cnt;
139 environ[cnt + 1] = NULL;
91 } 140 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */ 141 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2)))) 142 malloc((size_t)((int)(np - name) + l_value + 2))))
95 return (-1); 143 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 144 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 145 ;
98 for (*C++ = '='; *C++ = *value++; ) 146 for (*C++ = '='; (*C++ = *value++); )
99 ; 147 ;
100 return (0); 148 return (0);
101} 149}
@@ -104,17 +152,29 @@ setenv(name, value, rewrite)
104 * unsetenv(name) -- 152 * unsetenv(name) --
105 * Delete environmental variable "name". 153 * Delete environmental variable "name".
106 */ 154 */
107void 155int
108unsetenv(name) 156unsetenv(const char *name)
109 const char *name;
110{ 157{
111 extern char **environ; 158 char **P;
112 register char **P; 159 const char *np;
113 int offset; 160 int offset = 0;
114 char *__findenv();
115 161
116 while (__findenv(name, &offset)) /* if set multiple times */ 162 if (!name || !*name) {
163 errno = EINVAL;
164 return (-1);
165 }
166 for (np = name; *np && *np != '='; ++np)
167 ;
168 if (*np) {
169 errno = EINVAL;
170 return (-1); /* has `=' in name */
171 }
172
173 /* could be set multiple times */
174 while (__findenv(name, (int)(np - name), &offset)) {
117 for (P = &environ[offset];; ++P) 175 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1))) 176 if (!(*P = *(P + 1)))
119 break; 177 break;
178 }
179 return (0);
120} 180}