Blame src/gl/unsetenv.c

Packit Service 991b93
/* Copyright (C) 1992, 1995-2002, 2005-2020 Free Software Foundation, Inc.
Packit aea12f
   This file is part of the GNU C Library.
Packit aea12f
Packit aea12f
   This program is free software: you can redistribute it and/or modify
Packit aea12f
   it under the terms of the GNU General Public License as published by
Packit aea12f
   the Free Software Foundation; either version 3 of the License, or
Packit aea12f
   (at your option) any later version.
Packit aea12f
Packit aea12f
   This program is distributed in the hope that it will be useful,
Packit aea12f
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit aea12f
   GNU General Public License for more details.
Packit aea12f
Packit aea12f
   You should have received a copy of the GNU General Public License
Packit aea12f
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit aea12f
Packit aea12f
/* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
Packit aea12f
   optimizes away the name == NULL test below.  */
Packit aea12f
#define _GL_ARG_NONNULL(params)
Packit aea12f
Packit aea12f
#include <config.h>
Packit aea12f
Packit aea12f
/* Specification.  */
Packit aea12f
#include <stdlib.h>
Packit aea12f
Packit aea12f
#include <errno.h>
Packit aea12f
#if !_LIBC
Packit aea12f
# define __set_errno(ev) ((errno) = (ev))
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#include <string.h>
Packit aea12f
#include <unistd.h>
Packit aea12f
Packit aea12f
#if !_LIBC
Packit aea12f
# define __environ      environ
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#if _LIBC
Packit aea12f
/* This lock protects against simultaneous modifications of 'environ'.  */
Packit aea12f
# include <bits/libc-lock.h>
Packit aea12f
__libc_lock_define_initialized (static, envlock)
Packit aea12f
# define LOCK   __libc_lock_lock (envlock)
Packit aea12f
# define UNLOCK __libc_lock_unlock (envlock)
Packit aea12f
#else
Packit aea12f
# define LOCK
Packit aea12f
# define UNLOCK
Packit aea12f
#endif
Packit aea12f
Packit aea12f
/* In the GNU C library we must keep the namespace clean.  */
Packit aea12f
#ifdef _LIBC
Packit aea12f
# define unsetenv __unsetenv
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#if _LIBC || !HAVE_UNSETENV
Packit aea12f
Packit aea12f
int
Packit aea12f
unsetenv (const char *name)
Packit aea12f
{
Packit aea12f
  size_t len;
Packit aea12f
  char **ep;
Packit aea12f
Packit aea12f
  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
Packit aea12f
    {
Packit aea12f
      __set_errno (EINVAL);
Packit aea12f
      return -1;
Packit aea12f
    }
Packit aea12f
Packit aea12f
  len = strlen (name);
Packit aea12f
Packit aea12f
  LOCK;
Packit aea12f
Packit aea12f
  ep = __environ;
Packit aea12f
  while (*ep != NULL)
Packit aea12f
    if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
Packit aea12f
      {
Packit aea12f
        /* Found it.  Remove this pointer by moving later ones back.  */
Packit aea12f
        char **dp = ep;
Packit aea12f
Packit aea12f
        do
Packit aea12f
          dp[0] = dp[1];
Packit aea12f
        while (*dp++);
Packit aea12f
        /* Continue the loop in case NAME appears again.  */
Packit aea12f
      }
Packit aea12f
    else
Packit aea12f
      ++ep;
Packit aea12f
Packit aea12f
  UNLOCK;
Packit aea12f
Packit aea12f
  return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
#ifdef _LIBC
Packit aea12f
# undef unsetenv
Packit aea12f
weak_alias (__unsetenv, unsetenv)
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#else /* HAVE_UNSETENV */
Packit aea12f
Packit aea12f
# undef unsetenv
Packit aea12f
# if !HAVE_DECL_UNSETENV
Packit aea12f
#  if VOID_UNSETENV
Packit aea12f
extern void unsetenv (const char *);
Packit aea12f
#  else
Packit aea12f
extern int unsetenv (const char *);
Packit aea12f
#  endif
Packit aea12f
# endif
Packit aea12f
Packit aea12f
/* Call the underlying unsetenv, in case there is hidden bookkeeping
Packit aea12f
   that needs updating beyond just modifying environ.  */
Packit aea12f
int
Packit aea12f
rpl_unsetenv (const char *name)
Packit aea12f
{
Packit aea12f
  int result = 0;
Packit aea12f
  if (!name || !*name || strchr (name, '='))
Packit aea12f
    {
Packit aea12f
      errno = EINVAL;
Packit aea12f
      return -1;
Packit aea12f
    }
Packit aea12f
  while (getenv (name))
Packit aea12f
# if !VOID_UNSETENV
Packit aea12f
    result =
Packit aea12f
# endif
Packit aea12f
      unsetenv (name);
Packit aea12f
  return result;
Packit aea12f
}
Packit aea12f
Packit aea12f
#endif /* HAVE_UNSETENV */