summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2007-04-30 02:25:02 +0000
committerache <ache@FreeBSD.org>2007-04-30 02:25:02 +0000
commitdf3730247f93a1787d0ee43349ab60b1cda06dfb (patch)
treef3c51d97304bef50f993149ee17487bb6c86505e
parent142746f314eb83d957199603e2b6b281b0985625 (diff)
downloadFreeBSD-src-df3730247f93a1787d0ee43349ab60b1cda06dfb.zip
FreeBSD-src-df3730247f93a1787d0ee43349ab60b1cda06dfb.tar.gz
Make setenv, putenv, getenv and unsetenv conforming to Open Group specs
Issue 6 (also IEEE Std 1003.1-2001) in following areas: args, return, errors. Putenv still needs rewriting because specs explicitly says that altering passed string later should change the environment (currently we copy the string so can't provide that).
-rw-r--r--lib/libc/stdlib/getenv.332
-rw-r--r--lib/libc/stdlib/getenv.c10
-rw-r--r--lib/libc/stdlib/putenv.c8
-rw-r--r--lib/libc/stdlib/setenv.c17
4 files changed, 48 insertions, 19 deletions
diff --git a/lib/libc/stdlib/getenv.3 b/lib/libc/stdlib/getenv.3
index 3d365f1..35547aa 100644
--- a/lib/libc/stdlib/getenv.3
+++ b/lib/libc/stdlib/getenv.3
@@ -50,21 +50,17 @@
.Ft int
.Fn setenv "const char *name" "const char *value" "int overwrite"
.Ft int
-.Fn putenv "const char *string"
-.Ft void
+.Fn putenv "char *string"
+.Ft int
.Fn unsetenv "const char *name"
.Sh DESCRIPTION
These functions set, unset and fetch environment variables from the
host
.Em environment list .
For compatibility with differing environment conventions,
-the given arguments
-.Fa name
-and
+the given argument
.Fa value
-may be appended and prepended,
-respectively,
-with an equal sign
+may be prepended with an equal sign
.Dq Li \&= .
.Pp
The
@@ -121,9 +117,21 @@ is not in the current environment,
.Dv NULL
is returned.
.Pp
-.Rv -std setenv putenv
+.Rv -std setenv putenv unsetenv
.Sh ERRORS
.Bl -tag -width Er
+.It Bq Er EINVAL
+The function
+.Fn setenv
+or
+.Fn unsetenv
+failed because the
+.Fa name
+is a
+.Dv NULL
+pointer, points to an empty string, or points to a string containing an
+.Dq Li \&=
+character.
.It Bq Er ENOMEM
The function
.Fn setenv
@@ -141,6 +149,12 @@ The
.Fn getenv
function conforms to
.St -isoC .
+The
+.Fn setenv
+and
+.Fn unsetenv
+functions conforms to
+.St -p1003.1-2001 .
.Sh HISTORY
The functions
.Fn setenv
diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c
index 306b6a1..73ac407 100644
--- a/lib/libc/stdlib/getenv.c
+++ b/lib/libc/stdlib/getenv.c
@@ -44,7 +44,6 @@ inline char *__findenv(const char *, int *);
* 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).
- * Explicitly removes '=' in argument name.
*
* This routine *should* be a static; don't use it.
*/
@@ -58,11 +57,9 @@ __findenv(name, offset)
const char *np;
char **p, *cp;
- if (name == NULL || environ == NULL)
+ if (environ == NULL)
return (NULL);
- for (np = name; *np && *np != '='; ++np)
- continue;
- len = np - name;
+ len = strlen(name);
for (p = environ; (cp = *p) != NULL; ++p) {
for (np = name, i = len; i && *cp; i--)
if (*cp++ != *np++)
@@ -85,5 +82,8 @@ getenv(name)
{
int offset;
+ if (name == NULL || !*name || strchr(name, '=') != NULL)
+ return (NULL);
+
return (__findenv(name, &offset));
}
diff --git a/lib/libc/stdlib/putenv.c b/lib/libc/stdlib/putenv.c
index a5eea5d..b6c7ccb 100644
--- a/lib/libc/stdlib/putenv.c
+++ b/lib/libc/stdlib/putenv.c
@@ -33,24 +33,28 @@ static char sccsid[] = "@(#)putenv.c 8.2 (Berkeley) 3/27/94";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
int
putenv(str)
- const char *str;
+ char *str;
{
char *p, *equal;
- int rval;
+ int rval, serrno;
if ((p = strdup(str)) == NULL)
return (-1);
if ((equal = index(p, '=')) == NULL) {
(void)free(p);
+ errno = EINVAL;
return (-1);
}
*equal = '\0';
rval = setenv(p, equal + 1, 1);
+ serrno = errno;
(void)free(p);
+ errno = serrno;
return (rval);
}
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
index 202c022..4f05f32 100644
--- a/lib/libc/stdlib/setenv.c
+++ b/lib/libc/stdlib/setenv.c
@@ -33,6 +33,7 @@ static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -55,6 +56,11 @@ setenv(name, value, rewrite)
char *c;
int l_value, offset;
+ if (name == NULL || !*name || strchr(name, '=') != NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen(value);
@@ -88,9 +94,8 @@ setenv(name, value, rewrite)
environ[cnt + 1] = NULL;
offset = cnt;
}
- for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */
if (!(environ[offset] = /* name + `=' + value */
- malloc((size_t)((int)(c - name) + l_value + 2))))
+ malloc((size_t)(strlen(name) + l_value + 2))))
return (-1);
for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
for (*c++ = '='; (*c++ = *value++); );
@@ -101,7 +106,7 @@ setenv(name, value, rewrite)
* unsetenv(name) --
* Delete environmental variable "name".
*/
-void
+int
unsetenv(name)
const char *name;
{
@@ -109,8 +114,14 @@ unsetenv(name)
char **p;
int offset;
+ if (name == NULL || !*name || strchr(name, '=') != NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
while (__findenv(name, &offset)) /* if set multiple times */
for (p = &environ[offset];; ++p)
if (!(*p = *(p + 1)))
break;
+ return (0);
}
OpenPOWER on IntegriCloud