Blame gnulib/lib/unsetenv.c

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