From f2a71cb78b94d1e80a3c888e09872da5aa30481f Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 6 Jun 2024 01:08:45 +0200 Subject: [PATCH] putenv: Improve comments. * lib/putenv.c (_unsetenv, putenv): Improve comments regarding native Windows. --- ChangeLog | 6 ++++++ lib/putenv.c | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9722b0bfd4..4cccffbc14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-06-05 Bruno Haible + + putenv: Improve comments. + * lib/putenv.c (_unsetenv, putenv): Improve comments regarding native + Windows. + 2024-06-03 Bruno Haible readlinkat: Work around a Cygwin 3.3.6 bug. diff --git a/lib/putenv.c b/lib/putenv.c index 5d339407a4..525d12aed9 100644 --- a/lib/putenv.c +++ b/lib/putenv.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2023 Free Software +/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2024 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C @@ -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 + + 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 + + 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 -- 2.39.5