Annotation of src/external/gpl3/binutils/dist/libiberty/setenv.c, Revision 1.1.1.1
1.1 skrll 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., 51 Franklin Street - Fifth Floor,
17: Boston, MA 02110-1301, 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 (const char *name, const char *value, int replace)
84: {
85: register char **ep = 0;
86: register size_t size;
87: const size_t namelen = strlen (name);
88: const size_t vallen = strlen (value) + 1;
89:
90: LOCK;
91:
92: size = 0;
93: if (__environ != NULL)
94: {
95: for (ep = __environ; *ep != NULL; ++ep)
96: if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
97: break;
98: else
99: ++size;
100: }
101:
102: if (__environ == NULL || *ep == NULL)
103: {
104: char **new_environ;
105: if (__environ == last_environ && __environ != NULL)
106: /* We allocated this space; we can extend it. */
107: new_environ = (char **) realloc (last_environ,
108: (size + 2) * sizeof (char *));
109: else
110: new_environ = (char **) malloc ((size + 2) * sizeof (char *));
111:
112: if (new_environ == NULL)
113: {
114: UNLOCK;
115: return -1;
116: }
117:
118: new_environ[size] = (char *) malloc (namelen + 1 + vallen);
119: if (new_environ[size] == NULL)
120: {
121: free ((char *) new_environ);
122: __set_errno (ENOMEM);
123: UNLOCK;
124: return -1;
125: }
126:
127: if (__environ != last_environ)
128: memcpy ((char *) new_environ, (char *) __environ,
129: size * sizeof (char *));
130:
131: memcpy (new_environ[size], name, namelen);
132: new_environ[size][namelen] = '=';
133: memcpy (&new_environ[size][namelen + 1], value, vallen);
134:
135: new_environ[size + 1] = NULL;
136:
137: last_environ = __environ = new_environ;
138: }
139: else if (replace)
140: {
141: size_t len = strlen (*ep);
142: if (len + 1 < namelen + 1 + vallen)
143: {
144: /* The existing string is too short; malloc a new one. */
145: char *new_string = (char *) malloc (namelen + 1 + vallen);
146: if (new_string == NULL)
147: {
148: UNLOCK;
149: return -1;
150: }
151: *ep = new_string;
152: }
153: memcpy (*ep, name, namelen);
154: (*ep)[namelen] = '=';
155: memcpy (&(*ep)[namelen + 1], value, vallen);
156: }
157:
158: UNLOCK;
159:
160: return 0;
161: }
162:
163: void
164: unsetenv (const char *name)
165: {
166: const size_t len = strlen (name);
167: char **ep;
168:
169: LOCK;
170:
171: for (ep = __environ; *ep; ++ep)
172: if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
173: {
174: /* Found it. Remove this pointer by moving later ones back. */
175: char **dp = ep;
176: do
177: dp[0] = dp[1];
178: while (*dp++);
179: /* Continue the loop in case NAME appears again. */
180: }
181:
182: UNLOCK;
183: }
CVSweb <webmaster@jp.NetBSD.org>