summaryrefslogtreecommitdiffstats
path: root/gl/unsetenv.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/unsetenv.c')
-rw-r--r--gl/unsetenv.c39
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)
56int 56int
57unsetenv (const char *name) 57unsetenv (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 *);
110int 135int
111rpl_unsetenv (const char *name) 136rpl_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 =