]>
Commit | Line | Data |
---|---|---|
c906108c | 1 | /* environ.c -- library for manipulating environments for GNU. |
69517000 | 2 | |
1d506c26 | 3 | Copyright (C) 1986-2024 Free Software Foundation, Inc. |
c906108c | 4 | |
c5aa993b JM |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 7 | the Free Software Foundation; either version 3 of the License, or |
c5aa993b | 8 | (at your option) any later version. |
c906108c | 9 | |
c5aa993b JM |
10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
c906108c | 14 | |
c5aa993b | 15 | You should have received a copy of the GNU General Public License |
a9762ec7 | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
c906108c | 17 | |
1672e0d9 | 18 | #include "common-defs.h" |
c906108c | 19 | #include "environ.h" |
325fac50 | 20 | #include <algorithm> |
9a6c7d9c | 21 | #include <utility> |
c5aa993b | 22 | |
268a13a5 | 23 | /* See gdbsupport/environ.h. */ |
c906108c | 24 | |
9a6c7d9c SDJ |
25 | gdb_environ & |
26 | gdb_environ::operator= (gdb_environ &&e) | |
c906108c | 27 | { |
9a6c7d9c SDJ |
28 | /* Are we self-moving? */ |
29 | if (&e == this) | |
30 | return *this; | |
31 | ||
c801f8f1 PW |
32 | this->clear (); |
33 | ||
9a6c7d9c | 34 | m_environ_vector = std::move (e.m_environ_vector); |
0a2dde4a SDJ |
35 | m_user_set_env = std::move (e.m_user_set_env); |
36 | m_user_unset_env = std::move (e.m_user_unset_env); | |
9a6c7d9c SDJ |
37 | e.m_environ_vector.clear (); |
38 | e.m_environ_vector.push_back (NULL); | |
0a2dde4a SDJ |
39 | e.m_user_set_env.clear (); |
40 | e.m_user_unset_env.clear (); | |
9a6c7d9c | 41 | return *this; |
c906108c SS |
42 | } |
43 | ||
268a13a5 | 44 | /* See gdbsupport/environ.h. */ |
c906108c | 45 | |
9a6c7d9c | 46 | gdb_environ gdb_environ::from_host_environ () |
c906108c SS |
47 | { |
48 | extern char **environ; | |
9a6c7d9c | 49 | gdb_environ e; |
c906108c SS |
50 | |
51 | if (environ == NULL) | |
9a6c7d9c | 52 | return e; |
c906108c | 53 | |
9a6c7d9c | 54 | for (int i = 0; environ[i] != NULL; ++i) |
c906108c | 55 | { |
9a6c7d9c SDJ |
56 | /* Make sure we add the element before the last (NULL). */ |
57 | e.m_environ_vector.insert (e.m_environ_vector.end () - 1, | |
58 | xstrdup (environ[i])); | |
c906108c SS |
59 | } |
60 | ||
9a6c7d9c SDJ |
61 | return e; |
62 | } | |
c906108c | 63 | |
268a13a5 | 64 | /* See gdbsupport/environ.h. */ |
d7f9d729 | 65 | |
9a6c7d9c SDJ |
66 | void |
67 | gdb_environ::clear () | |
68 | { | |
69 | for (char *v : m_environ_vector) | |
70 | xfree (v); | |
71 | m_environ_vector.clear (); | |
72 | /* Always add the NULL element. */ | |
73 | m_environ_vector.push_back (NULL); | |
0a2dde4a SDJ |
74 | m_user_set_env.clear (); |
75 | m_user_unset_env.clear (); | |
c906108c SS |
76 | } |
77 | ||
9a6c7d9c SDJ |
78 | /* Helper function to check if STRING contains an environment variable |
79 | assignment of VAR, i.e., if STRING starts with 'VAR='. Return true | |
80 | if it contains, false otherwise. */ | |
c906108c | 81 | |
9a6c7d9c | 82 | static bool |
0a2dde4a | 83 | match_var_in_string (const char *string, const char *var, size_t var_len) |
c906108c | 84 | { |
9a6c7d9c SDJ |
85 | if (strncmp (string, var, var_len) == 0 && string[var_len] == '=') |
86 | return true; | |
87 | ||
88 | return false; | |
c906108c | 89 | } |
c906108c | 90 | |
268a13a5 | 91 | /* See gdbsupport/environ.h. */ |
9a6c7d9c SDJ |
92 | |
93 | const char * | |
94 | gdb_environ::get (const char *var) const | |
c906108c | 95 | { |
9a6c7d9c | 96 | size_t len = strlen (var); |
c906108c | 97 | |
9a6c7d9c SDJ |
98 | for (char *el : m_environ_vector) |
99 | if (el != NULL && match_var_in_string (el, var, len)) | |
100 | return &el[len + 1]; | |
c906108c | 101 | |
9a6c7d9c | 102 | return NULL; |
c906108c SS |
103 | } |
104 | ||
268a13a5 | 105 | /* See gdbsupport/environ.h. */ |
c906108c SS |
106 | |
107 | void | |
9a6c7d9c | 108 | gdb_environ::set (const char *var, const char *value) |
c906108c | 109 | { |
85f0dd3c | 110 | char *fullvar = concat (var, "=", value, (char *) NULL); |
0a2dde4a | 111 | |
9a6c7d9c | 112 | /* We have to unset the variable in the vector if it exists. */ |
0a2dde4a | 113 | unset (var, false); |
c906108c | 114 | |
9a6c7d9c | 115 | /* Insert the element before the last one, which is always NULL. */ |
0a2dde4a SDJ |
116 | m_environ_vector.insert (m_environ_vector.end () - 1, fullvar); |
117 | ||
118 | /* Mark this environment variable as having been set by the user. | |
119 | This will be useful when we deal with setting environment | |
120 | variables on the remote target. */ | |
121 | m_user_set_env.insert (std::string (fullvar)); | |
122 | ||
123 | /* If this environment variable is marked as unset by the user, then | |
124 | remove it from the list, because now the user wants to set | |
125 | it. */ | |
126 | m_user_unset_env.erase (std::string (var)); | |
c906108c SS |
127 | } |
128 | ||
268a13a5 | 129 | /* See gdbsupport/environ.h. */ |
c906108c SS |
130 | |
131 | void | |
0a2dde4a | 132 | gdb_environ::unset (const char *var, bool update_unset_list) |
c906108c | 133 | { |
9a6c7d9c | 134 | size_t len = strlen (var); |
0a2dde4a | 135 | std::vector<char *>::iterator it_env; |
9a6c7d9c | 136 | |
d4c6ce5b | 137 | /* We iterate until '.end () - 1' because the last element is |
9a6c7d9c | 138 | always NULL. */ |
0a2dde4a SDJ |
139 | for (it_env = m_environ_vector.begin (); |
140 | it_env != m_environ_vector.end () - 1; | |
141 | ++it_env) | |
142 | if (match_var_in_string (*it_env, var, len)) | |
143 | break; | |
144 | ||
145 | if (it_env != m_environ_vector.end () - 1) | |
146 | { | |
147 | m_user_set_env.erase (std::string (*it_env)); | |
148 | xfree (*it_env); | |
149 | ||
150 | m_environ_vector.erase (it_env); | |
151 | } | |
152 | ||
153 | if (update_unset_list) | |
154 | m_user_unset_env.insert (std::string (var)); | |
155 | } | |
156 | ||
268a13a5 | 157 | /* See gdbsupport/environ.h. */ |
0a2dde4a SDJ |
158 | |
159 | void | |
160 | gdb_environ::unset (const char *var) | |
161 | { | |
162 | unset (var, true); | |
9a6c7d9c | 163 | } |
c906108c | 164 | |
268a13a5 | 165 | /* See gdbsupport/environ.h. */ |
9a6c7d9c SDJ |
166 | |
167 | char ** | |
168 | gdb_environ::envp () const | |
169 | { | |
170 | return const_cast<char **> (&m_environ_vector[0]); | |
c906108c | 171 | } |
0a2dde4a | 172 | |
268a13a5 | 173 | /* See gdbsupport/environ.h. */ |
0a2dde4a SDJ |
174 | |
175 | const std::set<std::string> & | |
176 | gdb_environ::user_set_env () const | |
177 | { | |
178 | return m_user_set_env; | |
179 | } | |
180 | ||
181 | const std::set<std::string> & | |
182 | gdb_environ::user_unset_env () const | |
183 | { | |
184 | return m_user_unset_env; | |
185 | } |