unsetenv.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Copyright (C) 1992, 1995-2002, 2005-2023 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. This file is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as
  5. published by the Free Software Foundation; either version 2.1 of the
  6. License, or (at your option) any later version.
  7. This file is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  13. /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
  14. optimizes away the name == NULL test below. */
  15. #define _GL_ARG_NONNULL(params)
  16. #include <config.h>
  17. /* Specification. */
  18. #include <stdlib.h>
  19. #include <errno.h>
  20. #if !_LIBC
  21. # define __set_errno(ev) ((errno) = (ev))
  22. #endif
  23. #include <string.h>
  24. #include <unistd.h>
  25. #if !_LIBC
  26. # define __environ environ
  27. #endif
  28. #if _LIBC
  29. /* This lock protects against simultaneous modifications of 'environ'. */
  30. # include <bits/libc-lock.h>
  31. __libc_lock_define_initialized (static, envlock)
  32. # define LOCK __libc_lock_lock (envlock)
  33. # define UNLOCK __libc_lock_unlock (envlock)
  34. #else
  35. # define LOCK
  36. # define UNLOCK
  37. #endif
  38. /* In the GNU C library we must keep the namespace clean. */
  39. #ifdef _LIBC
  40. # define unsetenv __unsetenv
  41. #endif
  42. #if _LIBC || !HAVE_UNSETENV
  43. int
  44. unsetenv (const char *name)
  45. {
  46. size_t len;
  47. char **ep;
  48. if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
  49. {
  50. __set_errno (EINVAL);
  51. return -1;
  52. }
  53. len = strlen (name);
  54. LOCK;
  55. ep = __environ;
  56. while (*ep != NULL)
  57. if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
  58. {
  59. /* Found it. Remove this pointer by moving later ones back. */
  60. char **dp = ep;
  61. do
  62. dp[0] = dp[1];
  63. while (*dp++);
  64. /* Continue the loop in case NAME appears again. */
  65. }
  66. else
  67. ++ep;
  68. UNLOCK;
  69. return 0;
  70. }
  71. #ifdef _LIBC
  72. # undef unsetenv
  73. weak_alias (__unsetenv, unsetenv)
  74. #endif
  75. #else /* HAVE_UNSETENV */
  76. # undef unsetenv
  77. # if !HAVE_DECL_UNSETENV
  78. # if VOID_UNSETENV
  79. extern void unsetenv (const char *);
  80. # else
  81. extern int unsetenv (const char *);
  82. # endif
  83. # endif
  84. /* Call the underlying unsetenv, in case there is hidden bookkeeping
  85. that needs updating beyond just modifying environ. */
  86. int
  87. rpl_unsetenv (const char *name)
  88. {
  89. int result = 0;
  90. if (!name || !*name || strchr (name, '='))
  91. {
  92. errno = EINVAL;
  93. return -1;
  94. }
  95. while (getenv (name))
  96. # if !VOID_UNSETENV
  97. result =
  98. # endif
  99. unsetenv (name);
  100. return result;
  101. }
  102. #endif /* HAVE_UNSETENV */