changeset 12307:a15e71d9f0b6

unsetenv: work around Solaris bug 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>
author Eric Blake <ebb9@byu.net>
date Tue, 17 Nov 2009 06:31:34 -0700
parents 5e0e6e795550
children 5dd13836d207
files ChangeLog lib/unsetenv.c m4/setenv.m4
diffstat 3 files changed, 30 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- a/lib/unsetenv.c
+++ b/lib/unsetenv.c
@@ -105,10 +105,11 @@
       errno = EINVAL;
       return -1;
     }
+  while (getenv (name))
 # if !VOID_UNSETENV
-  result =
+    result =
 # endif
-    unsetenv (name);
+      unsetenv (name);
   return result;
 }
 
--- a/m4/setenv.m4
+++ b/m4/setenv.m4
@@ -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_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 @@
       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
 ])