my previous version was wrong; this one is right
[unix-history] / usr / src / lib / libc / stdlib / setenv.c
CommitLineData
fd08e5b9
KB
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
019bea33 5 * %sccs.include.redist.c%
fd08e5b9
KB
6 */
7
8#if defined(LIBC_SCCS) && !defined(lint)
f0a345ab 9static char sccsid[] = "@(#)setenv.c 5.5 (Berkeley) %G%";
fd08e5b9
KB
10#endif /* LIBC_SCCS and not lint */
11
48780a31
KB
12#include <stddef.h>
13#include <stdlib.h>
f0a345ab 14#include <string.h>
fd08e5b9
KB
15
16/*
17 * setenv --
18 * Set the value of the environmental variable "name" to be
19 * "value". If rewrite is set, replace any current value.
20 */
21setenv(name, value, rewrite)
f0a345ab
DS
22 register const char *name;
23 register const char *value;
fd08e5b9
KB
24 int rewrite;
25{
26 extern char **environ;
27 static int alloced; /* if allocated space before */
28 register char *C;
29 int l_value, offset;
48780a31 30 char *_findenv();
fd08e5b9
KB
31
32 if (*value == '=') /* no `=' in value */
33 ++value;
34 l_value = strlen(value);
35 if ((C = _findenv(name, &offset))) { /* find if already exists */
36 if (!rewrite)
37 return(0);
38 if (strlen(C) >= l_value) { /* old larger; copy over */
39 while (*C++ = *value++);
40 return(0);
41 }
42 }
43 else { /* create new slot */
44 register int cnt;
45 register char **P;
46
47 for (P = environ, cnt = 0; *P; ++P, ++cnt);
48 if (alloced) { /* just increase size */
49 environ = (char **)realloc((char *)environ,
48780a31 50 (size_t)(sizeof(char *) * (cnt + 2)));
fd08e5b9
KB
51 if (!environ)
52 return(-1);
53 }
54 else { /* get new space */
55 alloced = 1; /* copy old entries into it */
48780a31 56 P = (char **)malloc((size_t)(sizeof(char *) *
fd08e5b9
KB
57 (cnt + 2)));
58 if (!P)
59 return(-1);
60 bcopy(environ, P, cnt * sizeof(char *));
61 environ = P;
62 }
63 environ[cnt + 1] = NULL;
64 offset = cnt;
65 }
f0a345ab 66 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
fd08e5b9 67 if (!(environ[offset] = /* name + `=' + value */
48780a31 68 malloc((size_t)((int)(C - name) + l_value + 2))))
fd08e5b9
KB
69 return(-1);
70 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
71 for (*C++ = '='; *C++ = *value++;);
72 return(0);
73}
74
75/*
76 * unsetenv(name) --
77 * Delete environmental variable "name".
78 */
79void
80unsetenv(name)
f0a345ab 81 const char *name;
fd08e5b9 82{
48780a31
KB
83 extern char **environ;
84 register char **P;
85 int offset;
fd08e5b9
KB
86
87 while (_findenv(name, &offset)) /* if set multiple times */
88 for (P = &environ[offset];; ++P)
89 if (!(*P = *(P + 1)))
90 break;
91}