source: branches/libc-0.6/src/binutils/libiberty/setenv.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.5 KB
Line 
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,
27the new value will be stored only if @var{overwrite} is nonzero.
28The companion @code{unsetenv} function removes @var{name} from the
29environment. 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)
48extern 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
64extern 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. */
79static char **last_environ;
80
81
82int
83setenv (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
166void
167unsetenv (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}
Note: See TracBrowser for help on using the repository browser.