summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/stdlib/getenv.319
-rw-r--r--lib/libc/stdlib/getenv.c7
-rw-r--r--lib/libc/stdlib/putenv.c46
-rw-r--r--lib/libc/stdlib/setenv.c12
4 files changed, 58 insertions, 26 deletions
diff --git a/lib/libc/stdlib/getenv.3 b/lib/libc/stdlib/getenv.3
index 1882ba2..7445b47 100644
--- a/lib/libc/stdlib/getenv.3
+++ b/lib/libc/stdlib/getenv.3
@@ -88,11 +88,17 @@ to the given
.Pp
The
.Fn putenv
-function takes an argument of the form ``name=value'' and is
-equivalent to:
-.Bd -literal -offset indent
-setenv(name, value, 1);
-.Ed
+function takes an argument of the form ``name=value'' and
+puts it directly into the current environment.
+If the variable
+.Fa name
+does not exist in the list,
+it is inserted with the given
+.Fa value .
+If the variable
+.Fa name
+does exist, it is reset to the given
+.Fa value .
.Pp
The
.Fn unsetenv
@@ -145,7 +151,8 @@ The
function conforms to
.St -isoC .
The
-.Fn setenv
+.Fn setenv ,
+.Fn putenv
and
.Fn unsetenv
functions conforms to
diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c
index 73ac407..9ff18d8 100644
--- a/lib/libc/stdlib/getenv.c
+++ b/lib/libc/stdlib/getenv.c
@@ -43,7 +43,8 @@ inline char *__findenv(const char *, int *);
* __findenv --
* Returns pointer to value associated with name, if any, else NULL.
* Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
+ * environmental array, for use by putenv(3), setenv(3) and unsetenv(3).
+ * Explicitly removes '=' in argument name.
*
* This routine *should* be a static; don't use it.
*/
@@ -59,7 +60,9 @@ __findenv(name, offset)
if (environ == NULL)
return (NULL);
- len = strlen(name);
+ for (np = name; *np && *np != '='; ++np)
+ continue;
+ len = np - name;
for (p = environ; (cp = *p) != NULL; ++p) {
for (np = name, i = len; i && *cp; i--)
if (*cp++ != *np++)
diff --git a/lib/libc/stdlib/putenv.c b/lib/libc/stdlib/putenv.c
index b6c7ccb..56b78cf 100644
--- a/lib/libc/stdlib/putenv.c
+++ b/lib/libc/stdlib/putenv.c
@@ -37,24 +37,46 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
+extern char **__alloced; /* if allocated space before */
+
+char *__findenv(const char *, int *);
+
int
putenv(str)
char *str;
{
- char *p, *equal;
- int rval, serrno;
+ extern char **environ;
+ char *eq;
+ int offset;
- if ((p = strdup(str)) == NULL)
- return (-1);
- if ((equal = index(p, '=')) == NULL) {
- (void)free(p);
+ if (str == NULL || (eq = strchr(str, '=')) == NULL || eq == str) {
errno = EINVAL;
return (-1);
}
- *equal = '\0';
- rval = setenv(p, equal + 1, 1);
- serrno = errno;
- (void)free(p);
- errno = serrno;
- return (rval);
+
+ /* Trimmed version of setenv(3). */
+ if (__findenv(str, &offset) == NULL) {
+ int cnt;
+ char **p;
+
+ for (p = environ, cnt = 0; *p; ++p, ++cnt);
+ if (__alloced == environ) { /* just increase size */
+ p = (char **)realloc((char *)environ,
+ (size_t)(sizeof(char *) * (cnt + 2)));
+ if (!p)
+ return (-1);
+ }
+ else { /* get new space */
+ /* copy old entries into it */
+ p = (char **)malloc((size_t)(sizeof(char *) * (cnt + 2)));
+ if (!p)
+ return (-1);
+ bcopy(environ, p, cnt * sizeof(char *));
+ }
+ __alloced = environ = p;
+ environ[cnt + 1] = NULL;
+ offset = cnt;
+ }
+ environ[offset] = str;
+ return (0);
}
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
index 2695af7..5725733 100644
--- a/lib/libc/stdlib/setenv.c
+++ b/lib/libc/stdlib/setenv.c
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
+char **__alloced; /* if allocated space before */
+
char *__findenv(const char *, int *);
/*
@@ -52,7 +54,6 @@ setenv(name, value, rewrite)
int rewrite;
{
extern char **environ;
- static char **alloced; /* if allocated space before */
char *c;
int l_value, offset;
@@ -74,26 +75,25 @@ setenv(name, value, rewrite)
char **p;
for (p = environ, cnt = 0; *p; ++p, ++cnt);
- if (alloced == environ) { /* just increase size */
+ if (__alloced == environ) { /* just increase size */
p = (char **)realloc((char *)environ,
(size_t)(sizeof(char *) * (cnt + 2)));
if (!p)
return (-1);
- alloced = environ = p;
}
else { /* get new space */
/* copy old entries into it */
- p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
+ p = (char **)malloc((size_t)(sizeof(char *) * (cnt + 2)));
if (!p)
return (-1);
bcopy(environ, p, cnt * sizeof(char *));
- alloced = environ = p;
}
+ __alloced = environ = p;
environ[cnt + 1] = NULL;
offset = cnt;
}
if (!(environ[offset] = /* name + `=' + value */
- malloc((size_t)(strlen(name) + l_value + 2))))
+ (char *)malloc((size_t)(strlen(name) + l_value + 2))))
return (-1);
for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
for (*c++ = '='; (*c++ = *value++); );
OpenPOWER on IntegriCloud