]> Savannah Git Hosting - gnulib.git/commitdiff
unsetenv: On native Windows, don't modify _environ directly.
authorBruno Haible <bruno@clisp.org>
Wed, 5 Jun 2024 23:21:28 +0000 (01:21 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 6 Jun 2024 00:32:24 +0000 (02:32 +0200)
* m4/setenv.m4 (gl_PREREQ_UNSETENV): Check for _putenv.
* lib/unsetenv.c (unsetenv): Add native Windows handling, from
lib/putenv.c.
* modules/unsetenv (Depends-on): Add free-posix, malloc-posix.
* m4/putenv.m4 (gl_FUNC_PUTENV): Use AC_CHECK_DECLS_ONCE.
* lib/putenv.c (_unsetenv): Moved to lib/unsetenv.c.
(putenv): Invoke unsetenv instead of _unsetenv.
* modules/putenv-gnu (Depends-on): Add unsetenv.

ChangeLog
lib/putenv.c
lib/unsetenv.c
m4/putenv.m4
m4/setenv.m4
modules/putenv-gnu
modules/unsetenv

index 212bc3bb6faecfae141c6476e212bab4c3a94de4..4cd92956da7b9fe5d63d21a267de07fa03c4c8ee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2024-06-05  Bruno Haible  <bruno@clisp.org>
+
+       unsetenv: On native Windows, don't modify _environ directly.
+       * m4/setenv.m4 (gl_PREREQ_UNSETENV): Check for _putenv.
+       * lib/unsetenv.c (unsetenv): Add native Windows handling, from
+       lib/putenv.c.
+       * modules/unsetenv (Depends-on): Add free-posix, malloc-posix.
+       * m4/putenv.m4 (gl_FUNC_PUTENV): Use AC_CHECK_DECLS_ONCE.
+       * lib/putenv.c (_unsetenv): Moved to lib/unsetenv.c.
+       (putenv): Invoke unsetenv instead of _unsetenv.
+       * modules/putenv-gnu (Depends-on): Add unsetenv.
+
 2024-06-05  Bruno Haible  <bruno@clisp.org>
 
        putenv: Don't crash upon out-of-memory.
index 1d70717e0f7f9456b5b6bc12c47ed0603a330d1c..d3084c9e6077d59f48a6dba86499539a14f77608 100644 (file)
@@ -64,71 +64,6 @@ __libc_lock_define_initialized (static, envlock)
 # define SetEnvironmentVariable SetEnvironmentVariableA
 #endif
 
-static int
-_unsetenv (const char *name)
-{
-  size_t len;
-
-  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
-  len = strlen (name);
-
-#if HAVE_DECL__PUTENV /* native Windows */
-  /* The Microsoft documentation
-     <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv>
-     says:
-       "Don't change an environment entry directly: instead,
-        use _putenv or _wputenv to change it."
-     Note: Microsoft's _putenv updates not only the contents of _environ but
-     also the contents of _wenviron, so that both are in kept in sync.
-
-     The way to remove an environment variable is to pass to _putenv a string
-     of the form "NAME=".  (NB: This is a different convention than with glibc
-     putenv, which expects a string of the form "NAME"!)  */
-  {
-    int putenv_result;
-    char *name_ = malloc (len + 2);
-    if (name_ == NULL)
-      return -1;
-    memcpy (name_, name, len);
-    name_[len] = '=';
-    name_[len + 1] = 0;
-    putenv_result = _putenv (name_);
-    /* In this particular case it is OK to free() the argument passed to
-       _putenv.  */
-    free (name_);
-    return putenv_result;
-  }
-#else
-
-  LOCK;
-
-  char **ep = environ;
-  while (*ep != NULL)
-    if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
-      {
-        /* Found it.  Remove this pointer by moving later ones back.  */
-        char **dp = ep;
-
-        do
-          dp[0] = dp[1];
-        while (*dp++);
-        /* Continue the loop in case NAME appears again.  */
-      }
-    else
-      ++ep;
-
-  UNLOCK;
-
-  return 0;
-#endif
-}
-
-
 /* Put STRING, which is of the form "NAME=VALUE", in the environment.
    If STRING contains no '=', then remove STRING from the environment.  */
 int
@@ -140,7 +75,7 @@ putenv (char *string)
   if (name_end == NULL)
     {
       /* Remove the variable from the environment.  */
-      return _unsetenv (string);
+      return unsetenv (string);
     }
 
 #if HAVE_DECL__PUTENV /* native Windows */
index d8ada2aaed83ce17dc07e557c48498e51ccbd8eb..5e989968c1e987c1b3fdea28d21a2899e35c031b 100644 (file)
@@ -57,7 +57,6 @@ int
 unsetenv (const char *name)
 {
   size_t len;
-  char **ep;
 
   if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
     {
@@ -67,9 +66,37 @@ unsetenv (const char *name)
 
   len = strlen (name);
 
+#if HAVE_DECL__PUTENV /* native Windows */
+  /* The Microsoft documentation
+     <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv>
+     says:
+       "Don't change an environment entry directly: instead,
+        use _putenv or _wputenv to change it."
+     Note: Microsoft's _putenv updates not only the contents of _environ but
+     also the contents of _wenviron, so that both are in kept in sync.
+
+     The way to remove an environment variable is to pass to _putenv a string
+     of the form "NAME=".  (NB: This is a different convention than with glibc
+     putenv, which expects a string of the form "NAME"!)  */
+  {
+    int putenv_result;
+    char *name_ = malloc (len + 2);
+    if (name_ == NULL)
+      return -1;
+    memcpy (name_, name, len);
+    name_[len] = '=';
+    name_[len + 1] = 0;
+    putenv_result = _putenv (name_);
+    /* In this particular case it is OK to free() the argument passed to
+       _putenv.  */
+    free (name_);
+    return putenv_result;
+  }
+#else
+
   LOCK;
 
-  ep = __environ;
+  char **ep = __environ;
   while (*ep != NULL)
     if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
       {
@@ -87,6 +114,7 @@ unsetenv (const char *name)
   UNLOCK;
 
   return 0;
+#endif
 }
 
 #ifdef _LIBC
index 5179105dc74a82dfc4892df03fc9019505a9fafc..5616fdf558a3a2f61df8ba305a4ba839c83bf366 100644 (file)
@@ -1,5 +1,5 @@
 # putenv.m4
-# serial 27
+# serial 28
 dnl Copyright (C) 2002-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -61,5 +61,5 @@ AC_DEFUN([gl_FUNC_PUTENV],
 # Prerequisites of lib/putenv.c.
 AC_DEFUN([gl_PREREQ_PUTENV],
 [
-  AC_CHECK_DECLS([_putenv])
+  AC_CHECK_DECLS_ONCE([_putenv])
 ])
index e7f00f398e4240034c19b163fd91eb7c466a9b1d..2ff7868461d6cf37a2bb954b3ccf4bbffda1d3a2 100644 (file)
@@ -1,5 +1,5 @@
 # setenv.m4
-# serial 33
+# serial 34
 dnl Copyright (C) 2001-2004, 2006-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -163,4 +163,5 @@ AC_DEFUN([gl_PREREQ_UNSETENV],
 [
   AC_REQUIRE([gl_ENVIRON])
   AC_CHECK_HEADERS_ONCE([unistd.h])
+  AC_CHECK_DECLS_ONCE([_putenv])
 ])
index be929f60bebcc3a7f89867ebad8f77d4c0a61a06..356a74bdc78c97b70fabd5e59a44b121d2bdd164 100644 (file)
@@ -10,6 +10,7 @@ stdlib
 environ         [test $REPLACE_PUTENV = 1]
 free-posix      [test $REPLACE_PUTENV = 1]
 malloc-posix    [test $REPLACE_PUTENV = 1]
+unsetenv        [test $REPLACE_PUTENV = 1]
 
 configure.ac:
 gl_FUNC_PUTENV
index 0e603a5b7611d56206ce090b261a8adcb695e687..302d97081437332bff5a44fdf2ede09eb12dc8f4 100644 (file)
@@ -9,6 +9,8 @@ Depends-on:
 stdlib
 unistd          [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1]
 environ         [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1]
+free-posix      [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1]
+malloc-posix    [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1]
 
 configure.ac:
 gl_FUNC_UNSETENV