]>
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 RP |
22 | #include "environ.h" |
23 | #include <string.h> | |
51b57ded | 24 | #include "defs.h" /* For strsave(). */ |
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 | ||
67 | for (i = 0; environ[i]; i++) /*EMPTY*/; | |
68 | ||
69 | if (e->allocated < i) | |
70 | { | |
71 | e->allocated = max (i, e->allocated + 10); | |
72 | e->vector = (char **) xrealloc ((char *)e->vector, | |
73 | (e->allocated + 1) * sizeof (char *)); | |
74 | } | |
75 | ||
0685d95f | 76 | memcpy (e->vector, environ, (i + 1) * sizeof (char *)); |
bd5635a1 RP |
77 | |
78 | while (--i >= 0) | |
79 | { | |
80 | register int len = strlen (e->vector[i]); | |
81 | register char *new = (char *) xmalloc (len + 1); | |
0685d95f | 82 | memcpy (new, e->vector[i], len + 1); |
bd5635a1 RP |
83 | e->vector[i] = new; |
84 | } | |
85 | } | |
86 | ||
87 | /* Return the vector of environment E. | |
88 | This is used to get something to pass to execve. */ | |
89 | ||
90 | char ** | |
91 | environ_vector (e) | |
92 | struct environ *e; | |
93 | { | |
94 | return e->vector; | |
95 | } | |
96 | \f | |
97 | /* Return the value in environment E of variable VAR. */ | |
98 | ||
99 | char * | |
100 | get_in_environ (e, var) | |
51b57ded FF |
101 | const struct environ *e; |
102 | const char *var; | |
bd5635a1 RP |
103 | { |
104 | register int len = strlen (var); | |
105 | register char **vector = e->vector; | |
106 | register char *s; | |
107 | ||
51b57ded | 108 | for (; (s = *vector) != NULL; vector++) |
0685d95f | 109 | if (STREQN (s, var, len) && s[len] == '=') |
bd5635a1 RP |
110 | return &s[len + 1]; |
111 | ||
112 | return 0; | |
113 | } | |
114 | ||
115 | /* Store the value in E of VAR as VALUE. */ | |
116 | ||
117 | void | |
118 | set_in_environ (e, var, value) | |
119 | struct environ *e; | |
51b57ded FF |
120 | const char *var; |
121 | const char *value; | |
bd5635a1 RP |
122 | { |
123 | register int i; | |
124 | register int len = strlen (var); | |
125 | register char **vector = e->vector; | |
126 | register char *s; | |
127 | ||
51b57ded | 128 | for (i = 0; (s = vector[i]) != NULL; i++) |
0685d95f | 129 | if (STREQN (s, var, len) && s[len] == '=') |
bd5635a1 RP |
130 | break; |
131 | ||
132 | if (s == 0) | |
133 | { | |
134 | if (i == e->allocated) | |
135 | { | |
136 | e->allocated += 10; | |
137 | vector = (char **) xrealloc ((char *)vector, | |
138 | (e->allocated + 1) * sizeof (char *)); | |
139 | e->vector = vector; | |
140 | } | |
141 | vector[i + 1] = 0; | |
142 | } | |
143 | else | |
144 | free (s); | |
145 | ||
146 | s = (char *) xmalloc (len + strlen (value) + 2); | |
147 | strcpy (s, var); | |
148 | strcat (s, "="); | |
149 | strcat (s, value); | |
150 | vector[i] = s; | |
151 | ||
152 | /* Certain variables get exported back to the parent (e.g. our) | |
0685d95f JK |
153 | environment, too. FIXME: this is a hideous hack and should not be |
154 | allowed to live. What if we want to change the environment we pass to | |
155 | the program without affecting GDB's behavior? */ | |
156 | if (STREQ(var, "PATH") /* Object file location */ | |
157 | || STREQ (var, "G960BASE") /* Intel 960 downloads */ | |
158 | || STREQ (var, "G960BIN") /* Intel 960 downloads */ | |
159 | ) | |
160 | { | |
161 | putenv (strsave (s)); | |
162 | } | |
163 | ||
164 | /* This is a compatibility hack, since GDB 4.10 and older didn't have | |
165 | `set gnutarget'. Eventually it should go away, so that (for example) | |
166 | you can debug objdump's handling of GNUTARGET without affecting GDB's | |
167 | behavior. */ | |
168 | if (STREQ (var, "GNUTARGET")) | |
169 | { | |
170 | set_gnutarget (value); | |
171 | } | |
bd5635a1 RP |
172 | return; |
173 | } | |
174 | ||
175 | /* Remove the setting for variable VAR from environment E. */ | |
176 | ||
177 | void | |
178 | unset_in_environ (e, var) | |
179 | struct environ *e; | |
180 | char *var; | |
181 | { | |
182 | register int len = strlen (var); | |
183 | register char **vector = e->vector; | |
184 | register char *s; | |
185 | ||
51b57ded | 186 | for (; (s = *vector) != NULL; vector++) |
0685d95f JK |
187 | { |
188 | if (STREQN (s, var, len) && s[len] == '=') | |
189 | { | |
190 | free (s); | |
191 | /* Walk through the vector, shuffling args down by one, including | |
192 | the NULL terminator. Can't use memcpy() here since the regions | |
193 | overlap, and memmove() might not be available. */ | |
194 | while ((vector[0] = vector[1]) != NULL) | |
195 | { | |
196 | vector++; | |
197 | } | |
198 | break; | |
199 | } | |
200 | } | |
bd5635a1 | 201 | } |