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