diff options
Diffstat (limited to 'src/lib/libc/stdlib/setenv.c')
| -rw-r--r-- | src/lib/libc/stdlib/setenv.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c index 36540ebb0c..242830d7b9 100644 --- a/src/lib/libc/stdlib/setenv.c +++ b/src/lib/libc/stdlib/setenv.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: setenv.c,v 1.9 2005/08/08 08:05:37 espie Exp $ */ | 1 | /* $OpenBSD: setenv.c,v 1.10 2009/06/03 15:52:16 millert Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 1987 Regents of the University of California. | 3 | * Copyright (c) 1987 Regents of the University of California. |
| 4 | * All rights reserved. | 4 | * All rights reserved. |
| @@ -28,12 +28,53 @@ | |||
| 28 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #include <errno.h> | ||
| 31 | #include <stdlib.h> | 32 | #include <stdlib.h> |
| 32 | #include <string.h> | 33 | #include <string.h> |
| 33 | 34 | ||
| 34 | char *__findenv(const char *name, int *offset); | 35 | char *__findenv(const char *name, int len, int *offset); |
| 35 | 36 | ||
| 36 | extern char **environ; | 37 | extern char **environ; |
| 38 | static 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 | */ | ||
| 45 | int | ||
| 46 | putenv(char *str) | ||
| 47 | { | ||
| 48 | char **P, *cp; | ||
| 49 | size_t cnt; | ||
| 50 | int offset; | ||
| 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 | return (0); | ||
| 62 | } | ||
| 63 | |||
| 64 | /* create new slot for string */ | ||
| 65 | for (P = environ; *P != NULL; P++) | ||
| 66 | ; | ||
| 67 | cnt = P - environ; | ||
| 68 | P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2)); | ||
| 69 | if (!P) | ||
| 70 | return (-1); | ||
| 71 | if (lastenv != environ) | ||
| 72 | memcpy(P, environ, cnt * sizeof(char *)); | ||
| 73 | lastenv = environ = P; | ||
| 74 | environ[cnt] = str; | ||
| 75 | environ[cnt + 1] = NULL; | ||
| 76 | return (0); | ||
| 77 | } | ||
| 37 | 78 | ||
| 38 | /* | 79 | /* |
| 39 | * setenv -- | 80 | * setenv -- |
| @@ -43,14 +84,21 @@ extern char **environ; | |||
| 43 | int | 84 | int |
| 44 | setenv(const char *name, const char *value, int rewrite) | 85 | setenv(const char *name, const char *value, int rewrite) |
| 45 | { | 86 | { |
| 46 | static char **lastenv; /* last value of environ */ | ||
| 47 | char *C; | 87 | char *C; |
| 88 | const char *np; | ||
| 48 | int l_value, offset; | 89 | int l_value, offset; |
| 49 | 90 | ||
| 50 | if (*value == '=') /* no `=' in value */ | 91 | for (np = name; *np && *np != '='; ++np) |
| 51 | ++value; | 92 | ; |
| 93 | #ifdef notyet | ||
| 94 | if (*np) { | ||
| 95 | errno = EINVAL; | ||
| 96 | return (-1); /* has `=' in name */ | ||
| 97 | } | ||
| 98 | #endif | ||
| 99 | |||
| 52 | l_value = strlen(value); | 100 | l_value = strlen(value); |
| 53 | if ((C = __findenv(name, &offset))) { /* find if already exists */ | 101 | if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { |
| 54 | if (!rewrite) | 102 | if (!rewrite) |
| 55 | return (0); | 103 | return (0); |
| 56 | if (strlen(C) >= l_value) { /* old larger; copy over */ | 104 | if (strlen(C) >= l_value) { /* old larger; copy over */ |
| @@ -74,10 +122,8 @@ setenv(const char *name, const char *value, int rewrite) | |||
| 74 | offset = cnt; | 122 | offset = cnt; |
| 75 | environ[cnt + 1] = NULL; | 123 | environ[cnt + 1] = NULL; |
| 76 | } | 124 | } |
| 77 | for (C = (char *)name; *C && *C != '='; ++C) | ||
| 78 | ; /* no `=' in name */ | ||
| 79 | if (!(environ[offset] = /* name + `=' + value */ | 125 | if (!(environ[offset] = /* name + `=' + value */ |
| 80 | malloc((size_t)((int)(C - name) + l_value + 2)))) | 126 | malloc((size_t)((int)(np - name) + l_value + 2)))) |
| 81 | return (-1); | 127 | return (-1); |
| 82 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) | 128 | for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) |
| 83 | ; | 129 | ; |
| @@ -90,14 +136,25 @@ setenv(const char *name, const char *value, int rewrite) | |||
| 90 | * unsetenv(name) -- | 136 | * unsetenv(name) -- |
| 91 | * Delete environmental variable "name". | 137 | * Delete environmental variable "name". |
| 92 | */ | 138 | */ |
| 93 | void | 139 | int |
| 94 | unsetenv(const char *name) | 140 | unsetenv(const char *name) |
| 95 | { | 141 | { |
| 96 | char **P; | 142 | char **P; |
| 143 | const char *np; | ||
| 97 | int offset; | 144 | int offset; |
| 98 | 145 | ||
| 99 | while (__findenv(name, &offset)) /* if set multiple times */ | 146 | for (np = name; *np && *np != '='; ++np) |
| 147 | ; | ||
| 148 | if (*np) { | ||
| 149 | errno = EINVAL; | ||
| 150 | return (-1); /* has `=' in name */ | ||
| 151 | } | ||
| 152 | |||
| 153 | /* could be set multiple times */ | ||
| 154 | while (__findenv(name, (int)(np - name), &offset)) { | ||
| 100 | for (P = &environ[offset];; ++P) | 155 | for (P = &environ[offset];; ++P) |
| 101 | if (!(*P = *(P + 1))) | 156 | if (!(*P = *(P + 1))) |
| 102 | break; | 157 | break; |
| 158 | } | ||
| 159 | return (0); | ||
| 103 | } | 160 | } |
