2008-09-24 Pawel Veselov <pawel.veselov@gmail.com>

Fix setenv/getenv/unsetenv to be OpenGroup compliant:
        * libc/include/stdlib.h (unsetenv, _unsetenv_r): Redefine with integer
        return types.
        * libc/stdlib/getenv_r.c (_findenv_r): Do no special processing with
        names that contain equal chars.
        * libc/stdlib/setenv.c: Redefine _unsetenv_r as returning int.
        * libc/stdlib/setenv_r.c (_setenv_r): Return -1 and set errno to
        EINVAL if name contains an equal sign.  Do not remove any equal signs
        from the value.
        (_unsetenv_r): Modified to return int.  Return -1 and set EINVAL
        if name contains equal sign.  Return -1 if no variable(s) were found
        and return 0 otherwise.
This commit is contained in:
Jeff Johnston 2008-09-25 01:23:08 +00:00
parent 62470d09ad
commit 37f996a2b2
5 changed files with 48 additions and 19 deletions

View File

@ -1,3 +1,18 @@
2008-09-24 Pawel Veselov <pawel.veselov@gmail.com>
Fix setenv/getenv/unsetenv to be OpenGroup compliant:
* libc/include/stdlib.h (unsetenv, _unsetenv_r): Redefine with integer
return types.
* libc/stdlib/getenv_r.c (_findenv_r): Do no special processing with
names that contain equal chars.
* libc/stdlib/setenv.c: Redefine _unsetenv_r as returning int.
* libc/stdlib/setenv_r.c (_setenv_r): Return -1 and set errno to
EINVAL if name contains an equal sign. Do not remove any equal signs
from the value.
(_unsetenv_r): Modified to return int. Return -1 and set EINVAL
if name contains equal sign. Return -1 if no variable(s) were found
and return 0 otherwise.
2008-09-19 Eric Blake <ebb9@byu.net> 2008-09-19 Eric Blake <ebb9@byu.net>
Supply missing POSIX errno values. Supply missing POSIX errno values.

View File

@ -174,8 +174,8 @@ unsigned long long _EXFUN(_strtoull_r,(struct _reent *, const char *__n, char **
#ifndef __CYGWIN__ #ifndef __CYGWIN__
_VOID _EXFUN(cfree,(_PTR)); _VOID _EXFUN(cfree,(_PTR));
void _EXFUN(unsetenv,(const char *__string)); int _EXFUN(unsetenv,(const char *__string));
void _EXFUN(_unsetenv_r,(struct _reent *, const char *__string)); int _EXFUN(_unsetenv_r,(struct _reent *, const char *__string));
#endif #endif
#endif /* ! __STRICT_ANSI__ */ #endif /* ! __STRICT_ANSI__ */

View File

@ -74,7 +74,6 @@ static char ***p_environ = &environ;
* Returns pointer to value associated with name, if any, else NULL. * Returns pointer to value associated with name, if any, else NULL.
* Sets offset to be the offset of the name/value combination in the * 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 setenv(3) and unsetenv(3).
* Explicitly removes '=' in argument name.
* *
* This routine *should* be a static; don't use it. * This routine *should* be a static; don't use it.
*/ */
@ -99,13 +98,8 @@ _DEFUN (_findenv_r, (reent_ptr, name, offset),
return NULL; return NULL;
} }
c = name; len = strlen(name);
len = 0; c = name + len;
while (*c && *c != '=')
{
c++;
len++;
}
for (p = *p_environ; *p; ++p) for (p = *p_environ; *p; ++p)
if (!strncmp (*p, name, len)) if (!strncmp (*p, name, len))

View File

@ -23,7 +23,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
extern void _unsetenv_r _PARAMS ((struct _reent *, const char *)); extern int _unsetenv_r _PARAMS ((struct _reent *, const char *));
/* /*
* setenv -- * setenv --
@ -44,11 +44,11 @@ _DEFUN (setenv, (name, value, rewrite),
* unsetenv(name) -- * unsetenv(name) --
* Delete environmental variable "name". * Delete environmental variable "name".
*/ */
void int
_DEFUN (unsetenv, (name), _DEFUN (unsetenv, (name),
_CONST char *name) _CONST char *name)
{ {
_unsetenv_r (_REENT, name); return _unsetenv_r (_REENT, name);
} }
#endif /* !_REENT_ONLY */ #endif /* !_REENT_ONLY */

View File

@ -27,6 +27,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <errno.h>
#include "envlock.h" #include "envlock.h"
extern char **environ; extern char **environ;
@ -43,6 +44,8 @@ extern char *_findenv_r _PARAMS ((struct _reent *, const char *, int *));
* _setenv_r -- * _setenv_r --
* Set the value of the environmental variable "name" to be * Set the value of the environmental variable "name" to be
* "value". If rewrite is set, replace any current value. * "value". If rewrite is set, replace any current value.
* If "name" contains equal sign, -1 is returned, and errno is
* set to EINVAL;
*/ */
int int
@ -56,10 +59,14 @@ _DEFUN (_setenv_r, (reent_ptr, name, value, rewrite),
register char *C; register char *C;
int l_value, offset; int l_value, offset;
if (strchr(name, '='))
{
errno = EINVAL;
return -1;
}
ENV_LOCK; ENV_LOCK;
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen (value); l_value = strlen (value);
if ((C = _findenv_r (reent_ptr, name, &offset))) if ((C = _findenv_r (reent_ptr, name, &offset)))
{ /* find if already exists */ { /* find if already exists */
@ -132,20 +139,33 @@ _DEFUN (_setenv_r, (reent_ptr, name, value, rewrite),
* _unsetenv_r(name) -- * _unsetenv_r(name) --
* Delete environmental variable "name". * Delete environmental variable "name".
*/ */
void int
_DEFUN (_unsetenv_r, (reent_ptr, name), _DEFUN (_unsetenv_r, (reent_ptr, name),
struct _reent *reent_ptr _AND struct _reent *reent_ptr _AND
_CONST char *name) _CONST char *name)
{ {
register char **P; register char **P;
int offset; int offset;
int rc;
if (strchr(name, '='))
{
errno = EINVAL;
return -1;
}
ENV_LOCK; ENV_LOCK;
rc = -1;
while (_findenv_r (reent_ptr, name, &offset)) /* if set multiple times */ while (_findenv_r (reent_ptr, name, &offset)) /* if set multiple times */
{
rc = 0;
for (P = &(*p_environ)[offset];; ++P) for (P = &(*p_environ)[offset];; ++P)
if (!(*P = *(P + 1))) if (!(*P = *(P + 1)))
break; break;
}
ENV_UNLOCK; ENV_UNLOCK;
return (rc);
} }