xref: /original-bsd/lib/libc/stdlib/setenv.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1987, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)setenv.c	8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 char *__findenv __P((const char *, int *));
17 
18 /*
19  * setenv --
20  *	Set the value of the environmental variable "name" to be
21  *	"value".  If rewrite is set, replace any current value.
22  */
23 setenv(name, value, rewrite)
24 	register const char *name;
25 	register const char *value;
26 	int rewrite;
27 {
28 	extern char **environ;
29 	static int alloced;			/* if allocated space before */
30 	register char *c;
31 	int l_value, offset;
32 
33 	if (*value == '=')			/* no `=' in value */
34 		++value;
35 	l_value = strlen(value);
36 	if ((c = __findenv(name, &offset))) {	/* find if already exists */
37 		if (!rewrite)
38 			return (0);
39 		if (strlen(c) >= l_value) {	/* old larger; copy over */
40 			while (*c++ = *value++);
41 			return (0);
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,
50 			    (size_t)(sizeof(char *) * (cnt + 2)));
51 			if (!environ)
52 				return (-1);
53 		}
54 		else {				/* get new space */
55 			alloced = 1;		/* copy old entries into it */
56 			p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
57 			if (!p)
58 				return (-1);
59 			bcopy(environ, p, cnt * sizeof(char *));
60 			environ = p;
61 		}
62 		environ[cnt + 1] = NULL;
63 		offset = cnt;
64 	}
65 	for (c = (char *)name; *c && *c != '='; ++c);	/* no `=' in name */
66 	if (!(environ[offset] =			/* name + `=' + value */
67 	    malloc((size_t)((int)(c - name) + l_value + 2))))
68 		return (-1);
69 	for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
70 	for (*c++ = '='; *c++ = *value++;);
71 	return (0);
72 }
73 
74 /*
75  * unsetenv(name) --
76  *	Delete environmental variable "name".
77  */
78 void
79 unsetenv(name)
80 	const char *name;
81 {
82 	extern char **environ;
83 	register char **p;
84 	int offset;
85 
86 	while (__findenv(name, &offset))	/* if set multiple times */
87 		for (p = &environ[offset];; ++p)
88 			if (!(*p = *(p + 1)))
89 				break;
90 }
91