1e93f7393Sniklas /* environ.c -- library for manipulating environments for GNU.
2*b725ae77Skettenis
3*b725ae77Skettenis Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000,
4*b725ae77Skettenis 2003 Free Software Foundation, Inc.
5e93f7393Sniklas
6e93f7393Sniklas This program is free software; you can redistribute it and/or modify
7e93f7393Sniklas it under the terms of the GNU General Public License as published by
8e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
9e93f7393Sniklas (at your option) any later version.
10e93f7393Sniklas
11e93f7393Sniklas This program is distributed in the hope that it will be useful,
12e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
13e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14e93f7393Sniklas GNU General Public License for more details.
15e93f7393Sniklas
16e93f7393Sniklas You should have received a copy of the GNU General Public License
17e93f7393Sniklas along with this program; if not, write to the Free Software
18*b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
19*b725ae77Skettenis Boston, MA 02111-1307, USA. */
20e93f7393Sniklas
21e93f7393Sniklas #define min(a, b) ((a) < (b) ? (a) : (b))
22e93f7393Sniklas #define max(a, b) ((a) > (b) ? (a) : (b))
23e93f7393Sniklas
24e93f7393Sniklas #include "defs.h"
25e93f7393Sniklas #include "environ.h"
26e93f7393Sniklas #include "gdb_string.h"
27e93f7393Sniklas
28*b725ae77Skettenis
29e93f7393Sniklas /* Return a new environment object. */
30e93f7393Sniklas
31e93f7393Sniklas struct environ *
make_environ(void)32*b725ae77Skettenis make_environ (void)
33e93f7393Sniklas {
34*b725ae77Skettenis struct environ *e;
35e93f7393Sniklas
36e93f7393Sniklas e = (struct environ *) xmalloc (sizeof (struct environ));
37e93f7393Sniklas
38e93f7393Sniklas e->allocated = 10;
39e93f7393Sniklas e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *));
40e93f7393Sniklas e->vector[0] = 0;
41e93f7393Sniklas return e;
42e93f7393Sniklas }
43e93f7393Sniklas
44e93f7393Sniklas /* Free an environment and all the strings in it. */
45e93f7393Sniklas
46e93f7393Sniklas void
free_environ(struct environ * e)47*b725ae77Skettenis free_environ (struct environ *e)
48e93f7393Sniklas {
49*b725ae77Skettenis char **vector = e->vector;
50e93f7393Sniklas
51e93f7393Sniklas while (*vector)
52*b725ae77Skettenis xfree (*vector++);
53e93f7393Sniklas
54*b725ae77Skettenis xfree (e);
55e93f7393Sniklas }
56e93f7393Sniklas
57e93f7393Sniklas /* Copy the environment given to this process into E.
58e93f7393Sniklas Also copies all the strings in it, so we can be sure
59e93f7393Sniklas that all strings in these environments are safe to free. */
60e93f7393Sniklas
61e93f7393Sniklas void
init_environ(struct environ * e)62*b725ae77Skettenis init_environ (struct environ *e)
63e93f7393Sniklas {
64e93f7393Sniklas extern char **environ;
65*b725ae77Skettenis int i;
66e93f7393Sniklas
67e93f7393Sniklas if (environ == NULL)
68e93f7393Sniklas return;
69e93f7393Sniklas
70e93f7393Sniklas for (i = 0; environ[i]; i++) /*EMPTY */ ;
71e93f7393Sniklas
72e93f7393Sniklas if (e->allocated < i)
73e93f7393Sniklas {
74e93f7393Sniklas e->allocated = max (i, e->allocated + 10);
75e93f7393Sniklas e->vector = (char **) xrealloc ((char *) e->vector,
76e93f7393Sniklas (e->allocated + 1) * sizeof (char *));
77e93f7393Sniklas }
78e93f7393Sniklas
79e93f7393Sniklas memcpy (e->vector, environ, (i + 1) * sizeof (char *));
80e93f7393Sniklas
81e93f7393Sniklas while (--i >= 0)
82e93f7393Sniklas {
83*b725ae77Skettenis int len = strlen (e->vector[i]);
84*b725ae77Skettenis char *new = (char *) xmalloc (len + 1);
85e93f7393Sniklas memcpy (new, e->vector[i], len + 1);
86e93f7393Sniklas e->vector[i] = new;
87e93f7393Sniklas }
88e93f7393Sniklas }
89e93f7393Sniklas
90e93f7393Sniklas /* Return the vector of environment E.
91e93f7393Sniklas This is used to get something to pass to execve. */
92e93f7393Sniklas
93e93f7393Sniklas char **
environ_vector(struct environ * e)94*b725ae77Skettenis environ_vector (struct environ *e)
95e93f7393Sniklas {
96e93f7393Sniklas return e->vector;
97e93f7393Sniklas }
98e93f7393Sniklas
99e93f7393Sniklas /* Return the value in environment E of variable VAR. */
100e93f7393Sniklas
101e93f7393Sniklas char *
get_in_environ(const struct environ * e,const char * var)102*b725ae77Skettenis get_in_environ (const struct environ *e, const char *var)
103e93f7393Sniklas {
104*b725ae77Skettenis int len = strlen (var);
105*b725ae77Skettenis char **vector = e->vector;
106*b725ae77Skettenis char *s;
107e93f7393Sniklas
108e93f7393Sniklas for (; (s = *vector) != NULL; vector++)
109*b725ae77Skettenis if (strncmp (s, var, len) == 0 && s[len] == '=')
110e93f7393Sniklas return &s[len + 1];
111e93f7393Sniklas
112e93f7393Sniklas return 0;
113e93f7393Sniklas }
114e93f7393Sniklas
115e93f7393Sniklas /* Store the value in E of VAR as VALUE. */
116e93f7393Sniklas
117e93f7393Sniklas void
set_in_environ(struct environ * e,const char * var,const char * value)118*b725ae77Skettenis set_in_environ (struct environ *e, const char *var, const char *value)
119e93f7393Sniklas {
120*b725ae77Skettenis int i;
121*b725ae77Skettenis int len = strlen (var);
122*b725ae77Skettenis char **vector = e->vector;
123*b725ae77Skettenis char *s;
124e93f7393Sniklas
125e93f7393Sniklas for (i = 0; (s = vector[i]) != NULL; i++)
126*b725ae77Skettenis if (strncmp (s, var, len) == 0 && s[len] == '=')
127e93f7393Sniklas break;
128e93f7393Sniklas
129e93f7393Sniklas if (s == 0)
130e93f7393Sniklas {
131e93f7393Sniklas if (i == e->allocated)
132e93f7393Sniklas {
133e93f7393Sniklas e->allocated += 10;
134e93f7393Sniklas vector = (char **) xrealloc ((char *) vector,
135e93f7393Sniklas (e->allocated + 1) * sizeof (char *));
136e93f7393Sniklas e->vector = vector;
137e93f7393Sniklas }
138e93f7393Sniklas vector[i + 1] = 0;
139e93f7393Sniklas }
140e93f7393Sniklas else
141*b725ae77Skettenis xfree (s);
142e93f7393Sniklas
143e93f7393Sniklas s = (char *) xmalloc (len + strlen (value) + 2);
144e93f7393Sniklas strcpy (s, var);
145e93f7393Sniklas strcat (s, "=");
146e93f7393Sniklas strcat (s, value);
147e93f7393Sniklas vector[i] = s;
148e93f7393Sniklas
149e93f7393Sniklas /* This used to handle setting the PATH and GNUTARGET variables
150e93f7393Sniklas specially. The latter has been replaced by "set gnutarget"
151e93f7393Sniklas (which has worked since GDB 4.11). The former affects searching
152e93f7393Sniklas the PATH to find SHELL, and searching the PATH to find the
153e93f7393Sniklas argument of "symbol-file" or "exec-file". Maybe we should have
154e93f7393Sniklas some kind of "set exec-path" for that. But in any event, having
155e93f7393Sniklas "set env" affect anything besides the inferior is a bad idea.
156e93f7393Sniklas What if we want to change the environment we pass to the program
157e93f7393Sniklas without afecting GDB's behavior? */
158e93f7393Sniklas
159e93f7393Sniklas return;
160e93f7393Sniklas }
161e93f7393Sniklas
162e93f7393Sniklas /* Remove the setting for variable VAR from environment E. */
163e93f7393Sniklas
164e93f7393Sniklas void
unset_in_environ(struct environ * e,char * var)165*b725ae77Skettenis unset_in_environ (struct environ *e, char *var)
166e93f7393Sniklas {
167*b725ae77Skettenis int len = strlen (var);
168*b725ae77Skettenis char **vector = e->vector;
169*b725ae77Skettenis char *s;
170e93f7393Sniklas
171e93f7393Sniklas for (; (s = *vector) != NULL; vector++)
172e93f7393Sniklas {
173*b725ae77Skettenis if (DEPRECATED_STREQN (s, var, len) && s[len] == '=')
174e93f7393Sniklas {
175*b725ae77Skettenis xfree (s);
176e93f7393Sniklas /* Walk through the vector, shuffling args down by one, including
177e93f7393Sniklas the NULL terminator. Can't use memcpy() here since the regions
178e93f7393Sniklas overlap, and memmove() might not be available. */
179e93f7393Sniklas while ((vector[0] = vector[1]) != NULL)
180e93f7393Sniklas {
181e93f7393Sniklas vector++;
182e93f7393Sniklas }
183e93f7393Sniklas break;
184e93f7393Sniklas }
185e93f7393Sniklas }
186e93f7393Sniklas }
187