xref: /original-bsd/lib/libc/stdlib/setenv.c (revision 23730249)
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.6 (Berkeley) 06/04/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 	} else {					/* create new slot */
43 		register int	cnt;
44 		register char	**P;
45 
46 		for (P = environ, cnt = 0; *P; ++P, ++cnt);
47 		if (alloced) {			/* just increase size */
48 			environ = (char **)realloc((char *)environ,
49 			    (size_t)(sizeof(char *) * (cnt + 2)));
50 			if (!environ)
51 				return (-1);
52 		}
53 		else {				/* get new space */
54 			alloced = 1;		/* copy old entries into it */
55 			P = (char **)malloc((size_t)(sizeof(char *) *
56 			    (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 		;
71 	for (*C++ = '='; *C++ = *value++; )
72 		;
73 	return (0);
74 }
75 
76 /*
77  * unsetenv(name) --
78  *	Delete environmental variable "name".
79  */
80 void
81 unsetenv(name)
82 	const char	*name;
83 {
84 	extern char **environ;
85 	register char **P;
86 	int offset;
87 
88 	while (_findenv(name, &offset))		/* if set multiple times */
89 		for (P = &environ[offset];; ++P)
90 			if (!(*P = *(P + 1)))
91 				break;
92 }
93