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.c164
1 files changed, 111 insertions, 53 deletions
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index a36669888d..089ab92d38 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.13 2010/08/23 22:31:50 millert 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,120 @@
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 for (np = name; *np && *np != '='; ++np)
98 ;
99#ifdef notyet
100 if (*np) {
101 errno = EINVAL;
102 return (-1); /* has `=' in name */
103 }
104#endif
58 105
59 if (*value == '=') /* no `=' in value */
60 ++value;
61 l_value = strlen(value); 106 l_value = strlen(value);
62 if ((C = __findenv(name, &offset))) { /* find if already exists */ 107 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
108 int tmpoff = offset + 1;
63 if (!rewrite) 109 if (!rewrite)
64 return (0); 110 return (0);
111#if 0 /* XXX - existing entry may not be writable */
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 112 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 113 while ((*C++ = *value++))
114 ;
67 return (0); 115 return (0);
68 } 116 }
117#endif
118 /* could be set multiple times */
119 while (__findenv(name, (int)(np - name), &tmpoff)) {
120 for (P = &environ[tmpoff];; ++P)
121 if (!(*P = *(P + 1)))
122 break;
123 }
69 } else { /* create new slot */ 124 } else { /* create new slot */
70 register int cnt; 125 size_t cnt;
71 register char **P;
72 126
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 127 for (P = environ; *P != NULL; P++)
74 if (alloced) { /* just increase size */ 128 ;
75 environ = (char **)realloc((char *)environ, 129 cnt = P - environ;
76 (size_t)(sizeof(char *) * (cnt + 2))); 130 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
77 if (!environ) 131 if (!P)
78 return (-1); 132 return (-1);
79 } 133 if (lastenv != environ)
80 else { /* get new space */ 134 memcpy(P, environ, cnt * sizeof(char *));
81 alloced = 1; /* copy old entries into it */ 135 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; 136 offset = cnt;
137 environ[cnt + 1] = NULL;
91 } 138 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */ 139 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2)))) 140 malloc((size_t)((int)(np - name) + l_value + 2))))
95 return (-1); 141 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 142 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 143 ;
98 for (*C++ = '='; *C++ = *value++; ) 144 for (*C++ = '='; (*C++ = *value++); )
99 ; 145 ;
100 return (0); 146 return (0);
101} 147}
@@ -104,17 +150,29 @@ setenv(name, value, rewrite)
104 * unsetenv(name) -- 150 * unsetenv(name) --
105 * Delete environmental variable "name". 151 * Delete environmental variable "name".
106 */ 152 */
107void 153int
108unsetenv(name) 154unsetenv(const char *name)
109 const char *name;
110{ 155{
111 extern char **environ; 156 char **P;
112 register char **P; 157 const char *np;
113 int offset; 158 int offset = 0;
114 char *__findenv(); 159
160 if (!name || !*name) {
161 errno = EINVAL;
162 return (-1);
163 }
164 for (np = name; *np && *np != '='; ++np)
165 ;
166 if (*np) {
167 errno = EINVAL;
168 return (-1); /* has `=' in name */
169 }
115 170
116 while (__findenv(name, &offset)) /* if set multiple times */ 171 /* could be set multiple times */
172 while (__findenv(name, (int)(np - name), &offset)) {
117 for (P = &environ[offset];; ++P) 173 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1))) 174 if (!(*P = *(P + 1)))
119 break; 175 break;
176 }
177 return (0);
120} 178}