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