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