diff options
Diffstat (limited to 'gl/unsetenv.c')
| -rw-r--r-- | gl/unsetenv.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/gl/unsetenv.c b/gl/unsetenv.c index d8ada2aa..dab1b90c 100644 --- a/gl/unsetenv.c +++ b/gl/unsetenv.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1992, 1995-2002, 2005-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1992, 1995-2002, 2005-2026 Free Software Foundation, Inc. |
| 2 | This file is part of the GNU C Library. | 2 | This file is part of the GNU C Library. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| @@ -56,20 +56,44 @@ __libc_lock_define_initialized (static, envlock) | |||
| 56 | int | 56 | int |
| 57 | unsetenv (const char *name) | 57 | unsetenv (const char *name) |
| 58 | { | 58 | { |
| 59 | size_t len; | ||
| 60 | char **ep; | ||
| 61 | |||
| 62 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | 59 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) |
| 63 | { | 60 | { |
| 64 | __set_errno (EINVAL); | 61 | __set_errno (EINVAL); |
| 65 | return -1; | 62 | return -1; |
| 66 | } | 63 | } |
| 67 | 64 | ||
| 68 | len = strlen (name); | 65 | size_t len = strlen (name); |
| 66 | |||
| 67 | #if HAVE_DECL__PUTENV /* native Windows */ | ||
| 68 | /* The Microsoft documentation | ||
| 69 | <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv> | ||
| 70 | says: | ||
| 71 | "Don't change an environment entry directly: instead, | ||
| 72 | use _putenv or _wputenv to change it." | ||
| 73 | Note: Microsoft's _putenv updates not only the contents of _environ but | ||
| 74 | also the contents of _wenviron, so that both are in kept in sync. | ||
| 75 | |||
| 76 | The way to remove an environment variable is to pass to _putenv a string | ||
| 77 | of the form "NAME=". (NB: This is a different convention than with glibc | ||
| 78 | putenv, which expects a string of the form "NAME"!) */ | ||
| 79 | { | ||
| 80 | char *name_ = malloc (len + 2); | ||
| 81 | if (name_ == NULL) | ||
| 82 | return -1; | ||
| 83 | memcpy (name_, name, len); | ||
| 84 | name_[len] = '='; | ||
| 85 | name_[len + 1] = 0; | ||
| 86 | int putenv_result = _putenv (name_); | ||
| 87 | /* In this particular case it is OK to free() the argument passed to | ||
| 88 | _putenv. */ | ||
| 89 | free (name_); | ||
| 90 | return putenv_result; | ||
| 91 | } | ||
| 92 | #else | ||
| 69 | 93 | ||
| 70 | LOCK; | 94 | LOCK; |
| 71 | 95 | ||
| 72 | ep = __environ; | 96 | char **ep = __environ; |
| 73 | while (*ep != NULL) | 97 | while (*ep != NULL) |
| 74 | if (!strncmp (*ep, name, len) && (*ep)[len] == '=') | 98 | if (!strncmp (*ep, name, len) && (*ep)[len] == '=') |
| 75 | { | 99 | { |
| @@ -87,6 +111,7 @@ unsetenv (const char *name) | |||
| 87 | UNLOCK; | 111 | UNLOCK; |
| 88 | 112 | ||
| 89 | return 0; | 113 | return 0; |
| 114 | #endif | ||
| 90 | } | 115 | } |
| 91 | 116 | ||
| 92 | #ifdef _LIBC | 117 | #ifdef _LIBC |
| @@ -110,12 +135,12 @@ extern int unsetenv (const char *); | |||
| 110 | int | 135 | int |
| 111 | rpl_unsetenv (const char *name) | 136 | rpl_unsetenv (const char *name) |
| 112 | { | 137 | { |
| 113 | int result = 0; | ||
| 114 | if (!name || !*name || strchr (name, '=')) | 138 | if (!name || !*name || strchr (name, '=')) |
| 115 | { | 139 | { |
| 116 | errno = EINVAL; | 140 | errno = EINVAL; |
| 117 | return -1; | 141 | return -1; |
| 118 | } | 142 | } |
| 143 | int result = 0; | ||
| 119 | while (getenv (name)) | 144 | while (getenv (name)) |
| 120 | # if !VOID_UNSETENV | 145 | # if !VOID_UNSETENV |
| 121 | result = | 146 | result = |
