OSDN Git Service

2008-09-24 Pawel Veselov <pawel.veselov@gmail.com>
authorjjohnstn <jjohnstn>
Thu, 25 Sep 2008 01:23:08 +0000 (01:23 +0000)
committerjjohnstn <jjohnstn>
Thu, 25 Sep 2008 01:23:08 +0000 (01:23 +0000)
        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.

newlib/ChangeLog
newlib/libc/include/stdlib.h
newlib/libc/stdlib/getenv_r.c
newlib/libc/stdlib/setenv.c
newlib/libc/stdlib/setenv_r.c

index 4440a71..4d2fa61 100644 (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>
 
        Supply missing POSIX errno values.
index 9bee3b1..5f2f608 100644 (file)
@@ -174,8 +174,8 @@ unsigned long long _EXFUN(_strtoull_r,(struct _reent *, const char *__n, char **
 
 #ifndef __CYGWIN__
 _VOID  _EXFUN(cfree,(_PTR));
-void   _EXFUN(unsetenv,(const char *__string));
-void   _EXFUN(_unsetenv_r,(struct _reent *, const char *__string));
+int    _EXFUN(unsetenv,(const char *__string));
+int    _EXFUN(_unsetenv_r,(struct _reent *, const char *__string));
 #endif
 
 #endif /* ! __STRICT_ANSI__ */
index 85d250b..bfa9682 100644 (file)
@@ -74,7 +74,6 @@ static char ***p_environ = &environ;
  *     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.
  */
@@ -99,13 +98,8 @@ _DEFUN (_findenv_r, (reent_ptr, name, offset),
       return NULL;
     }
 
-  c = name;
-  len = 0;
-  while (*c && *c != '=')
-    {
-      c++;
-      len++;
-    }
+  len = strlen(name);
+  c = name + len;
 
   for (p = *p_environ; *p; ++p)
     if (!strncmp (*p, name, len))
index 746ce67..d423678 100644 (file)
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-extern void _unsetenv_r _PARAMS ((struct _reent *, const char *));
+extern int _unsetenv_r _PARAMS ((struct _reent *, const char *));
 
 /*
  * setenv --
@@ -44,11 +44,11 @@ _DEFUN (setenv, (name, value, rewrite),
  * unsetenv(name) --
  *     Delete environmental variable "name".
  */
-void
+int
 _DEFUN (unsetenv, (name),
         _CONST char *name)
 {
-  _unsetenv_r (_REENT, name);
+  return _unsetenv_r (_REENT, name);
 }
 
 #endif /* !_REENT_ONLY */
index 694bd14..e9ae76e 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <errno.h>
 #include "envlock.h"
 
 extern char **environ;
@@ -43,6 +44,8 @@ extern char *_findenv_r _PARAMS ((struct _reent *, const char *, int *));
  * _setenv_r --
  *     Set the value of the environmental variable "name" to be
  *     "value".  If rewrite is set, replace any current value.
+ *     If "name" contains equal sign, -1 is returned, and errno is
+ *     set to EINVAL;
  */
 
 int
@@ -56,10 +59,14 @@ _DEFUN (_setenv_r, (reent_ptr, name, value, rewrite),
   register char *C;
   int l_value, offset;
 
+  if (strchr(name, '='))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
   ENV_LOCK;
 
-  if (*value == '=')           /* no `=' in value */
-    ++value;
   l_value = strlen (value);
   if ((C = _findenv_r (reent_ptr, name, &offset)))
     {                          /* find if already exists */
@@ -132,20 +139,33 @@ _DEFUN (_setenv_r, (reent_ptr, name, value, rewrite),
  * _unsetenv_r(name) --
  *     Delete environmental variable "name".
  */
-void
+int
 _DEFUN (_unsetenv_r, (reent_ptr, name),
         struct _reent *reent_ptr _AND
         _CONST char *name)
 {
   register char **P;
   int offset;
+  int rc;
+  
+  if (strchr(name, '='))
+    {
+      errno = EINVAL;
+      return -1;
+    }
 
   ENV_LOCK;
 
+  rc = -1;
+
   while (_findenv_r (reent_ptr, name, &offset))        /* if set multiple times */
-    for (P = &(*p_environ)[offset];; ++P)
-      if (!(*P = *(P + 1)))
-       break;
+    { 
+      rc = 0;
+      for (P = &(*p_environ)[offset];; ++P)
+        if (!(*P = *(P + 1)))
+         break;
+    }
 
   ENV_UNLOCK;
+  return (rc);
 }