unsetenv: work around Solaris bug
authorEric Blake <ebb9@byu.net>
Tue, 17 Nov 2009 13:31:34 +0000 (06:31 -0700)
committerEric Blake <ebb9@byu.net>
Tue, 17 Nov 2009 13:31:34 +0000 (06:31 -0700)
unsetenv(name) only cleared the first instance, even if (ab)use of
putenv, or assignment to environ, included duplicates of name.

* m4/setenv.m4 (gl_FUNC_UNSETENV): Check for bug.
* lib/unsetenv.c (rpl_unsetenv): Work around it.
Reported by Jim Meyering.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/unsetenv.c
m4/setenv.m4

index e4179347a12541cde6e478bb9a26bf6529c83c7a..4dbb0d35ab8ce5a7a4c22dc85774d4a6daad8ec1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-11-17  Eric Blake  <ebb9@byu.net>
 
+       unsetenv: work around Solaris bug
+       * m4/setenv.m4 (gl_FUNC_UNSETENV): Check for bug.
+       * lib/unsetenv.c (rpl_unsetenv): Work around it.
+       Reported by Jim Meyering.
+
        vasnprintf: avoid compiler warnings
        * lib/vasnprintf.c (VASNPRINTF): Avoid shadowing our own local
        variables.
index 75670119de44fa4b4fe9c49b7cbec394ddc19a17..21fb1999def986754eb6c916b3867efdfd5c3dac 100644 (file)
@@ -105,10 +105,11 @@ rpl_unsetenv (const char *name)
       errno = EINVAL;
       return -1;
     }
+  while (getenv (name))
 # if !VOID_UNSETENV
-  result =
+    result =
 # endif
-    unsetenv (name);
+      unsetenv (name);
   return result;
 }
 
index ca146d2c0b628c62b46fc1ddc88c958c24c82236..a5df034aa650d45ce06fa04f3482db3ce2a61ae0 100644 (file)
@@ -1,4 +1,4 @@
-# setenv.m4 serial 12
+# setenv.m4 serial 13
 dnl Copyright (C) 2001-2004, 2006-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,7 @@ AC_DEFUN([gl_FUNC_UNSETENV],
     AC_LIBOBJ([unsetenv])
     gl_PREREQ_UNSETENV
   else
+    dnl Some BSDs return void, failing to do error checking.
     AC_CACHE_CHECK([for unsetenv() return type], [gt_cv_func_unsetenv_ret],
       [AC_TRY_COMPILE([#include <stdlib.h>
 extern
@@ -68,6 +69,26 @@ int unsetenv();
       REPLACE_UNSETENV=1
       AC_LIBOBJ([unsetenv])
     fi
+
+    dnl Solaris 10 unsetenv does not remove all copies of a name.
+    AC_CACHE_CHECK([whether unsetenv works on duplicates],
+      [gl_cv_func_unsetenv_works],
+      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+       #include <stdlib.h>
+      ]], [[
+       char entry[] = "b=2";
+       if (putenv ("a=1")) return 1;
+       if (putenv (entry)) return 2;
+       entry[0] = 'a';
+       unsetenv ("a");
+       if (getenv ("a")) return 3;
+      ]])],
+      [gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no],
+      [gl_cv_func_unsetenv_works="guessing no"])])
+    if test "$gl_cv_func_unsetenv_works" != yes; then
+      REPLACE_UNSETENV=1
+      AC_LIBOBJ([unsetenv])
+    fi
   fi
 ])