1208599Srdivacky/* Copyright (C) 1992,1995-1999,2000-2002 Free Software Foundation, Inc.
2208599Srdivacky   This file is part of the GNU C Library.
3208599Srdivacky
4208599Srdivacky   This program is free software; you can redistribute it and/or modify
5208599Srdivacky   it under the terms of the GNU General Public License as published by
6208599Srdivacky   the Free Software Foundation; either version 2, or (at your option)
7208599Srdivacky   any later version.
8208599Srdivacky
9208599Srdivacky   This program is distributed in the hope that it will be useful,
10208599Srdivacky   but WITHOUT ANY WARRANTY; without even the implied warranty of
11208599Srdivacky   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12208599Srdivacky   GNU General Public License for more details.
13208599Srdivacky
14208599Srdivacky   You should have received a copy of the GNU General Public License along
15208599Srdivacky   with this program; if not, write to the Free Software Foundation,
16208599Srdivacky   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17208599Srdivacky#include <sys/cdefs.h>
18208599Srdivacky__RCSID("$NetBSD: unsetenv.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
19208599Srdivacky
20208599Srdivacky
21208599Srdivacky#if HAVE_CONFIG_H
22208599Srdivacky# include <config.h>
23245431Sdim#endif
24208599Srdivacky
25208599Srdivacky#include <errno.h>
26208599Srdivacky#if !_LIBC
27208599Srdivacky# if !defined errno && !defined HAVE_ERRNO_DECL
28208599Srdivackyextern int errno;
29208599Srdivacky# endif
30208599Srdivacky# define __set_errno(ev) ((errno) = (ev))
31263509Sdim#endif
32263509Sdim
33263509Sdim#include <stdlib.h>
34263509Sdim#include <string.h>
35263509Sdim#if _LIBC || HAVE_UNISTD_H
36263509Sdim# include <unistd.h>
37263509Sdim#endif
38263509Sdim
39263509Sdim#if !_LIBC
40263509Sdim# define __environ	environ
41263509Sdim# ifndef HAVE_ENVIRON_DECL
42208599Srdivackyextern char **environ;
43252723Sdim# endif
44252723Sdim#endif
45245431Sdim
46208599Srdivacky#if _LIBC
47208599Srdivacky/* This lock protects against simultaneous modifications of `environ'.  */
48208599Srdivacky# include <bits/libc-lock.h>
49208599Srdivacky__libc_lock_define_initialized (static, envlock)
50208599Srdivacky# define LOCK	__libc_lock_lock (envlock)
51208599Srdivacky# define UNLOCK	__libc_lock_unlock (envlock)
52208599Srdivacky#else
53208599Srdivacky# define LOCK
54208599Srdivacky# define UNLOCK
55208599Srdivacky#endif
56208599Srdivacky
57208599Srdivacky/* In the GNU C library we must keep the namespace clean.  */
58208599Srdivacky#ifdef _LIBC
59210299Sed# define unsetenv __unsetenv
60208599Srdivacky#endif
61208599Srdivacky
62245431Sdim
63210299Sedint
64208599Srdivackyunsetenv (const char *name)
65210299Sed{
66208599Srdivacky  size_t len;
67208599Srdivacky  char **ep;
68210299Sed
69208599Srdivacky  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
70208599Srdivacky    {
71210299Sed      __set_errno (EINVAL);
72208599Srdivacky      return -1;
73208599Srdivacky    }
74210299Sed
75208599Srdivacky  len = strlen (name);
76208599Srdivacky
77263509Sdim  LOCK;
78263509Sdim
79263509Sdim  ep = __environ;
80210299Sed  while (*ep != NULL)
81263509Sdim    if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
82263509Sdim      {
83263509Sdim	/* Found it.  Remove this pointer by moving later ones back.  */
84263509Sdim	char **dp = ep;
85263509Sdim
86208599Srdivacky	do
87208599Srdivacky	  dp[0] = dp[1];
88208599Srdivacky	while (*dp++);
89208599Srdivacky	/* Continue the loop in case NAME appears again.  */
90208599Srdivacky      }
91208599Srdivacky    else
92218893Sdim      ++ep;
93218893Sdim
94218893Sdim  UNLOCK;
95218893Sdim
96218893Sdim  return 0;
97218893Sdim}
98218893Sdim
99218893Sdim#ifdef _LIBC
100# undef unsetenv
101weak_alias (__unsetenv, unsetenv)
102#endif
103