xref: /original-bsd/lib/libc/stdlib/setenv.c (revision b7cc7b86)
1 /*
2  * Copyright (c) 1987 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)setenv.c	5.5 (Berkeley) 02/23/91";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <string.h>
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  */
21 setenv(name, value, rewrite)
22 	register const char *name;
23 	register const char *value;
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;
30 	char *_findenv();
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,
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 = (char **)malloc((size_t)(sizeof(char *) *
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 	}
66 	for (C = (char *)name; *C && *C != '='; ++C);	/* no `=' in name */
67 	if (!(environ[offset] =			/* name + `=' + value */
68 	    malloc((size_t)((int)(C - name) + l_value + 2))))
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  */
79 void
80 unsetenv(name)
81 	const char	*name;
82 {
83 	extern char **environ;
84 	register char **P;
85 	int offset;
86 
87 	while (_findenv(name, &offset))		/* if set multiple times */
88 		for (P = &environ[offset];; ++P)
89 			if (!(*P = *(P + 1)))
90 				break;
91 }
92