build: Remove redundant check for `struct timespec'.
[bpt/guile.git] / lib / putenv.c
index ec5fe1a..2abc6ac 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2011 Free Software
+/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2013 Free Software
    Foundation, Inc.
 
    NOTE: The canonical source of this file is maintained with the GNU C
 
 #if _LIBC
 # if HAVE_GNU_LD
-# define environ __environ
+#  define environ __environ
 # else
 extern char **environ;
 # endif
 #endif
 
 #if _LIBC
-/* This lock protects against simultaneous modifications of `environ'.  */
+/* This lock protects against simultaneous modifications of 'environ'.  */
 # include <bits/libc-lock.h>
 __libc_lock_define_initialized (static, envlock)
 # define LOCK   __libc_lock_lock (envlock)
@@ -91,7 +91,7 @@ _unsetenv (const char *name)
 
 
 /* Put STRING, which is of the form "NAME=VALUE", in the environment.
-   If STRING contains no `=', then remove STRING from the environment.  */
+   If STRING contains no '=', then remove STRING from the environment.  */
 int
 putenv (char *string)
 {
@@ -115,6 +115,37 @@ putenv (char *string)
 
   if (*ep == NULL)
     {
+#if HAVE__PUTENV
+      /* Rely on _putenv to allocate the new environment.  If other
+         parts of the application use _putenv, the !HAVE__PUTENV code
+         would fight over who owns the environ vector, causing a crash.  */
+      if (name_end[1])
+        return _putenv (string);
+      else
+        {
+          /* _putenv ("NAME=") unsets NAME, so invoke _putenv ("NAME=x")
+             to allocate the environ vector and then replace the new
+             entry with "NAME=".  */
+          int putenv_result, putenv_errno;
+          char *name_x = malloc (name_end - string + sizeof "=x");
+          if (!name_x)
+            return -1;
+          memcpy (name_x, string, name_end - string + 1);
+          name_x[name_end - string + 1] = 'x';
+          name_x[name_end - string + 2] = 0;
+          putenv_result = _putenv (name_x);
+          putenv_errno = errno;
+          for (ep = environ; *ep; ep++)
+            if (*ep == name_x)
+              {
+                *ep = string;
+                break;
+              }
+          free (name_x);
+          __set_errno (putenv_errno);
+          return putenv_result;
+        }
+#else
       static char **last_environ = NULL;
       char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
       if (new_environ == NULL)
@@ -126,6 +157,7 @@ putenv (char *string)
       free (last_environ);
       last_environ = new_environ;
       environ = new_environ;
+#endif
     }
   else
     *ep = string;