]> Savannah Git Hosting - gnulib.git/commitdiff
putenv: Improve comments.
authorBruno Haible <bruno@clisp.org>
Wed, 5 Jun 2024 23:08:45 +0000 (01:08 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 6 Jun 2024 23:00:18 +0000 (01:00 +0200)
* lib/putenv.c (_unsetenv, putenv): Improve comments regarding native
Windows.

ChangeLog
lib/putenv.c

index ebf06f64f08fb7ba5241512f1b4f64bb545f6d54..25fb5df2e067f8d29ee7ae4fe4ba45919425c832 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-06-05  Bruno Haible  <bruno@clisp.org>
+
+       putenv: Improve comments.
+       * lib/putenv.c (_unsetenv, putenv): Improve comments regarding native
+       Windows.
+
 2024-06-04  Collin Funk  <collin.funk1@gmail.com>
 
        boot-time, readutmp: Fix missing MinGW include (regr. 2024-05-24).
index 2ab6f248db9d2e0c3a3428cda33cbb312289fe9d..525d12aed971c26792161446b1e9148223def2bc 100644 (file)
@@ -68,9 +68,6 @@ static int
 _unsetenv (const char *name)
 {
   size_t len;
-#if !HAVE_DECL__PUTENV
-  char **ep;
-#endif
 
   if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
     {
@@ -80,7 +77,18 @@ _unsetenv (const char *name)
 
   len = strlen (name);
 
-#if HAVE_DECL__PUTENV
+#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);
@@ -88,6 +96,8 @@ _unsetenv (const char *name)
     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;
   }
@@ -95,7 +105,7 @@ _unsetenv (const char *name)
 
   LOCK;
 
-  ep = environ;
+  char **ep = environ;
   while (*ep != NULL)
     if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
       {
@@ -131,10 +141,18 @@ putenv (char *string)
       return _unsetenv (string);
     }
 
-#if HAVE_DECL__PUTENV
-  /* Rely on _putenv to allocate the new environment.  If other
-     parts of the application use _putenv, the !HAVE_DECL__PUTENV code
-     would fight over who owns the environ vector, causing a crash.  */
+#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.
+
+     If we didn't follow this advice, our code and other parts of the
+     application (that use _putenv) would fight over who owns the environ vector
+     and thus cause a crash.  */
   if (name_end[1])
     return _putenv (string);
   else