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).
This commit is contained in:
parent
2f51d93626
commit
bdda893471
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user