1/* Copyright (C) 1992,1995-1999,2000-2002,2005-2006 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3
4   The GNU C Library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Library General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   The GNU C Library 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 GNU
12   Library General Public License for more details.
13
14   You should have received a copy of the GNU Library General Public
15   License along with the GNU C Library; see the file COPYING.LIB.  If not,
16   write to the Free Software Foundation, Inc., 51 Franklin Street,
17   Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <errno.h>
24#if !_LIBC
25# define __set_errno(ev) ((errno) = (ev))
26#endif
27
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31
32#if !_LIBC
33# define __environ	environ
34# ifndef HAVE_ENVIRON_DECL
35extern char **environ;
36# endif
37#endif
38
39#if _LIBC
40/* This lock protects against simultaneous modifications of `environ'.  */
41# include <bits/libc-lock.h>
42__libc_lock_define_initialized (static, envlock)
43# define LOCK	__libc_lock_lock (envlock)
44# define UNLOCK	__libc_lock_unlock (envlock)
45#else
46# define LOCK
47# define UNLOCK
48#endif
49
50/* In the GNU C library we must keep the namespace clean.  */
51#ifdef _LIBC
52# define unsetenv __unsetenv
53#endif
54
55
56int
57unsetenv (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
94weak_alias (__unsetenv, unsetenv)
95#endif
96