~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/libiberty/setenv.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 1992, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
 
2
   This file based on setenv.c in 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., 59 Temple Place - Suite 330,
 
17
   Boston, MA 02111-1307, USA.  */
 
18
 
 
19
 
 
20
/*
 
21
 
 
22
@deftypefn Supplemental int setenv (const char *@var{name}, const char *@var{value}, int @var{overwrite})
 
23
@deftypefnx Supplemental void unsetenv (const char *@var{name})
 
24
 
 
25
@code{setenv} adds @var{name} to the environment with value
 
26
@var{value}.  If the name was already present in the environment,
 
27
the new value will be stored only if @var{overwrite} is nonzero.
 
28
The companion @code{unsetenv} function removes @var{name} from the
 
29
environment.  This implementation is not safe for multithreaded code.
 
30
 
 
31
@end deftypefn
 
32
 
 
33
*/
 
34
 
 
35
#if HAVE_CONFIG_H
 
36
# include <config.h>
 
37
#endif
 
38
 
 
39
#define setenv libiberty_setenv
 
40
#define unsetenv libiberty_unsetenv
 
41
 
 
42
#include "ansidecl.h"
 
43
#include <sys/types.h> /* For `size_t' */
 
44
#include <stdio.h>     /* For `NULL' */
 
45
 
 
46
#include <errno.h>
 
47
#if !defined(errno) && !defined(HAVE_ERRNO_DECL)
 
48
extern int errno;
 
49
#endif
 
50
#define __set_errno(ev) ((errno) = (ev))
 
51
 
 
52
#if HAVE_STDLIB_H
 
53
# include <stdlib.h>
 
54
#endif
 
55
#if HAVE_STRING_H
 
56
# include <string.h>
 
57
#endif
 
58
#if HAVE_UNISTD_H
 
59
# include <unistd.h>
 
60
#endif
 
61
 
 
62
#define __environ       environ
 
63
#ifndef HAVE_ENVIRON_DECL
 
64
extern char **environ;
 
65
#endif
 
66
 
 
67
#undef setenv
 
68
#undef unsetenv
 
69
 
 
70
/* LOCK and UNLOCK are defined as no-ops.  This makes the libiberty
 
71
 * implementation MT-Unsafe. */
 
72
#define LOCK
 
73
#define UNLOCK
 
74
 
 
75
/* Below this point, it's verbatim code from the glibc-2.0 implementation */
 
76
 
 
77
/* If this variable is not a null pointer we allocated the current
 
78
   environment.  */
 
79
static char **last_environ;
 
80
 
 
81
 
 
82
int
 
83
setenv (name, value, replace)
 
84
     const char *name;
 
85
     const char *value;
 
86
     int replace;
 
87
{
 
88
  register char **ep = 0;
 
89
  register size_t size;
 
90
  const size_t namelen = strlen (name);
 
91
  const size_t vallen = strlen (value) + 1;
 
92
 
 
93
  LOCK;
 
94
 
 
95
  size = 0;
 
96
  if (__environ != NULL)
 
97
    {
 
98
      for (ep = __environ; *ep != NULL; ++ep)
 
99
        if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
 
100
          break;
 
101
        else
 
102
          ++size;
 
103
    }
 
104
 
 
105
  if (__environ == NULL || *ep == NULL)
 
106
    {
 
107
      char **new_environ;
 
108
      if (__environ == last_environ && __environ != NULL)
 
109
        /* We allocated this space; we can extend it.  */
 
110
        new_environ = (char **) realloc (last_environ,
 
111
                                         (size + 2) * sizeof (char *));
 
112
      else
 
113
        new_environ = (char **) malloc ((size + 2) * sizeof (char *));
 
114
 
 
115
      if (new_environ == NULL)
 
116
        {
 
117
          UNLOCK;
 
118
          return -1;
 
119
        }
 
120
 
 
121
      new_environ[size] = malloc (namelen + 1 + vallen);
 
122
      if (new_environ[size] == NULL)
 
123
        {
 
124
          free ((char *) new_environ);
 
125
          __set_errno (ENOMEM);
 
126
          UNLOCK;
 
127
          return -1;
 
128
        }
 
129
 
 
130
      if (__environ != last_environ)
 
131
        memcpy ((char *) new_environ, (char *) __environ,
 
132
                size * sizeof (char *));
 
133
 
 
134
      memcpy (new_environ[size], name, namelen);
 
135
      new_environ[size][namelen] = '=';
 
136
      memcpy (&new_environ[size][namelen + 1], value, vallen);
 
137
 
 
138
      new_environ[size + 1] = NULL;
 
139
 
 
140
      last_environ = __environ = new_environ;
 
141
    }
 
142
  else if (replace)
 
143
    {
 
144
      size_t len = strlen (*ep);
 
145
      if (len + 1 < namelen + 1 + vallen)
 
146
        {
 
147
          /* The existing string is too short; malloc a new one.  */
 
148
          char *new = malloc (namelen + 1 + vallen);
 
149
          if (new == NULL)
 
150
            {
 
151
              UNLOCK;
 
152
              return -1;
 
153
            }
 
154
          *ep = new;
 
155
        }
 
156
      memcpy (*ep, name, namelen);
 
157
      (*ep)[namelen] = '=';
 
158
      memcpy (&(*ep)[namelen + 1], value, vallen);
 
159
    }
 
160
 
 
161
  UNLOCK;
 
162
 
 
163
  return 0;
 
164
}
 
165
 
 
166
void
 
167
unsetenv (name)
 
168
     const char *name;
 
169
{
 
170
  const size_t len = strlen (name);
 
171
  char **ep;
 
172
 
 
173
  LOCK;
 
174
 
 
175
  for (ep = __environ; *ep; ++ep)
 
176
    if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
 
177
      {
 
178
        /* Found it.  Remove this pointer by moving later ones back.  */
 
179
        char **dp = ep;
 
180
        do
 
181
          dp[0] = dp[1];
 
182
        while (*dp++);
 
183
        /* Continue the loop in case NAME appears again.  */
 
184
      }
 
185
 
 
186
  UNLOCK;
 
187
}