Make use of Gnulib's `putenv' module.
[bpt/guile.git] / libguile / posix.c
index 78fd295..5f9b6cf 100644 (file)
@@ -21,6 +21,7 @@
 #  include <config.h>
 #endif
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
 
@@ -1512,98 +1513,13 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
   int rv;
   char *c_str = scm_to_locale_string (str);
 
-  if (strchr (c_str, '=') == NULL)
-    {
-      /* We want no "=" in the argument to mean remove the variable from the
-        environment, but not all putenv()s understand this, for example
-        FreeBSD 4.8 doesn't.  Getting it happening everywhere is a bit
-        painful.  What unsetenv() exists, we use that, of course.
-
-         Traditionally putenv("NAME") removes a variable, for example that's
-         what we have to do on Solaris 9 (it doesn't have an unsetenv).
-
-         But on DOS and on that DOS overlay manager thing called W-whatever,
-         putenv("NAME=") must be used (it too doesn't have an unsetenv).
-
-         Supposedly on AIX a putenv("NAME") could cause a segfault, but also
-         supposedly AIX 5.3 and up has unsetenv() available so should be ok
-         with the latter there.
-
-         For the moment we hard code the DOS putenv("NAME=") style under
-         __MINGW32__ and do the traditional everywhere else.  Such
-         system-name tests are bad, of course.  It'd be possible to use a
-         configure test when doing a a native build.  For example GNU R has
-         such a test (see R_PUTENV_AS_UNSETENV in
-         https://svn.r-project.org/R/trunk/m4/R.m4).  But when cross
-         compiling there'd want to be a guess, one probably based on the
-         system name (ie. mingw or not), thus landing back in basically the
-         present hard-coded situation.  Another possibility for a cross
-         build would be to try "NAME" then "NAME=" at runtime, if that's not
-         too much like overkill.  */
-
-#if HAVE_UNSETENV
-      /* when unsetenv() exists then we use it */
-      unsetenv (c_str);
-      free (c_str);
-#elif defined (__MINGW32__)
-      /* otherwise putenv("NAME=") on DOS */
-      int e;
-      size_t len = strlen (c_str);
-      char *ptr = scm_malloc (len + 2);
-      strcpy (ptr, c_str);
-      strcpy (ptr+len, "=");
-      rv = putenv (ptr);
-      e = errno; free (ptr); free (c_str); errno = e;
-      if (rv < 0)
-       SCM_SYSERROR;
-#else
-      /* otherwise traditional putenv("NAME") */
-      rv = putenv (c_str);
-      if (rv < 0)
-       SCM_SYSERROR;
-#endif
-    }
-  else
-    {
-#ifdef __MINGW32__
-      /* If str is "FOO=", ie. attempting to set an empty string, then
-         we need to see if it's been successful.  On MINGW, "FOO="
-         means remove FOO from the environment.  As a workaround, we
-         set "FOO= ", ie. a space, and then modify the string returned
-         by getenv.  It's not enough just to modify the string we set,
-         because MINGW putenv copies it.  */
-
-      {
-        size_t len = strlen (c_str);
-        if (c_str[len-1] == '=')
-          {
-            char *ptr = scm_malloc (len+2);
-            strcpy (ptr, c_str);
-            strcpy (ptr+len, " ");
-            rv = putenv (ptr);
-            if (rv < 0)
-              {
-                int eno = errno;
-                free (c_str);
-                errno = eno;
-                SCM_SYSERROR;
-              }
-            /* truncate to just the name */
-            c_str[len-1] = '\0';
-            ptr = getenv (c_str);
-            if (ptr)
-              ptr[0] = '\0';
-            return SCM_UNSPECIFIED;
-          }
-      }
-#endif /* __MINGW32__ */
+  /* Leave C_STR in the environment.  */
 
-      /* Leave c_str in the environment.  */
+  /* Gnulib's `putenv' module honors the semantics described above.  */
+  rv = putenv (c_str);
+  if (rv < 0)
+    SCM_SYSERROR;
 
-      rv = putenv (c_str);
-      if (rv < 0)
-       SCM_SYSERROR;
-    }
   return SCM_UNSPECIFIED;
 }
 #undef FUNC_NAME
@@ -1869,6 +1785,11 @@ SCM_DEFINE (scm_getlogin, "getlogin", 0, 0, 0,
 #endif /* HAVE_GETLOGIN */
 
 #if HAVE_CUSERID
+
+# if !HAVE_DECL_CUSERID
+extern char *cuserid (char *);
+# endif
+
 SCM_DEFINE (scm_cuserid, "cuserid", 0, 0, 0, 
             (void),
            "Return a string containing a user name associated with the\n"