xref: /openbsd-src/gnu/usr.bin/binutils/gdb/environ.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
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