Commit | Line | Data |
---|---|---|
c906108c | 1 | /* environ.c -- library for manipulating environments for GNU. |
69517000 | 2 | |
42a4f53d | 3 | Copyright (C) 1986-2019 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 | |
9a6c7d9c | 23 | /* See common/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 | ||
32 | m_environ_vector = std::move (e.m_environ_vector); | |
0a2dde4a SDJ |
33 | m_user_set_env = std::move (e.m_user_set_env); |
34 | m_user_unset_env = std::move (e.m_user_unset_env); | |
9a6c7d9c SDJ |
35 | e.m_environ_vector.clear (); |
36 | e.m_environ_vector.push_back (NULL); | |
0a2dde4a SDJ |
37 | e.m_user_set_env.clear (); |
38 | e.m_user_unset_env.clear (); | |
9a6c7d9c | 39 | return *this; |
c906108c SS |
40 | } |
41 | ||
9a6c7d9c | 42 | /* See common/environ.h. */ |
c906108c | 43 | |
9a6c7d9c | 44 | gdb_environ gdb_environ::from_host_environ () |
c906108c SS |
45 | { |
46 | extern char **environ; | |
9a6c7d9c | 47 | gdb_environ e; |
c906108c SS |
48 | |
49 | if (environ == NULL) | |
9a6c7d9c | 50 | return e; |
c906108c | 51 | |
9a6c7d9c | 52 | for (int i = 0; environ[i] != NULL; ++i) |
c906108c | 53 | { |
9a6c7d9c SDJ |
54 | /* Make sure we add the element before the last (NULL). */ |
55 | e.m_environ_vector.insert (e.m_environ_vector.end () - 1, | |
56 | xstrdup (environ[i])); | |
c906108c SS |
57 | } |
58 | ||
9a6c7d9c SDJ |
59 | return e; |
60 | } | |
c906108c | 61 | |
9a6c7d9c | 62 | /* See common/environ.h. */ |
d7f9d729 | 63 | |
9a6c7d9c SDJ |
64 | void |
65 | gdb_environ::clear () | |
66 | { | |
67 | for (char *v : m_environ_vector) | |
68 | xfree (v); | |
69 | m_environ_vector.clear (); | |
70 | /* Always add the NULL element. */ | |
71 | m_environ_vector.push_back (NULL); | |
0a2dde4a SDJ |
72 | m_user_set_env.clear (); |
73 | m_user_unset_env.clear (); | |
c906108c SS |
74 | } |
75 | ||
9a6c7d9c SDJ |
76 | /* Helper function to check if STRING contains an environment variable |
77 | assignment of VAR, i.e., if STRING starts with 'VAR='. Return true | |
78 | if it contains, false otherwise. */ | |
c906108c | 79 | |
9a6c7d9c | 80 | static bool |
0a2dde4a | 81 | match_var_in_string (const char *string, const char *var, size_t var_len) |
c906108c | 82 | { |
9a6c7d9c SDJ |
83 | if (strncmp (string, var, var_len) == 0 && string[var_len] == '=') |
84 | return true; | |
85 | ||
86 | return false; | |
c906108c | 87 | } |
c906108c | 88 | |
9a6c7d9c SDJ |
89 | /* See common/environ.h. */ |
90 | ||
91 | const char * | |
92 | gdb_environ::get (const char *var) const | |
c906108c | 93 | { |
9a6c7d9c | 94 | size_t len = strlen (var); |
c906108c | 95 | |
9a6c7d9c SDJ |
96 | for (char *el : m_environ_vector) |
97 | if (el != NULL && match_var_in_string (el, var, len)) | |
98 | return &el[len + 1]; | |
c906108c | 99 | |
9a6c7d9c | 100 | return NULL; |
c906108c SS |
101 | } |
102 | ||
9a6c7d9c | 103 | /* See common/environ.h. */ |
c906108c SS |
104 | |
105 | void | |
9a6c7d9c | 106 | gdb_environ::set (const char *var, const char *value) |
c906108c | 107 | { |
0a2dde4a SDJ |
108 | char *fullvar = concat (var, "=", value, NULL); |
109 | ||
9a6c7d9c | 110 | /* We have to unset the variable in the vector if it exists. */ |
0a2dde4a | 111 | unset (var, false); |
c906108c | 112 | |
9a6c7d9c | 113 | /* Insert the element before the last one, which is always NULL. */ |
0a2dde4a SDJ |
114 | m_environ_vector.insert (m_environ_vector.end () - 1, fullvar); |
115 | ||
116 | /* Mark this environment variable as having been set by the user. | |
117 | This will be useful when we deal with setting environment | |
118 | variables on the remote target. */ | |
119 | m_user_set_env.insert (std::string (fullvar)); | |
120 | ||
121 | /* If this environment variable is marked as unset by the user, then | |
122 | remove it from the list, because now the user wants to set | |
123 | it. */ | |
124 | m_user_unset_env.erase (std::string (var)); | |
c906108c SS |
125 | } |
126 | ||
9a6c7d9c | 127 | /* See common/environ.h. */ |
c906108c SS |
128 | |
129 | void | |
0a2dde4a | 130 | gdb_environ::unset (const char *var, bool update_unset_list) |
c906108c | 131 | { |
9a6c7d9c | 132 | size_t len = strlen (var); |
0a2dde4a | 133 | std::vector<char *>::iterator it_env; |
9a6c7d9c | 134 | |
d4c6ce5b | 135 | /* We iterate until '.end () - 1' because the last element is |
9a6c7d9c | 136 | always NULL. */ |
0a2dde4a SDJ |
137 | for (it_env = m_environ_vector.begin (); |
138 | it_env != m_environ_vector.end () - 1; | |
139 | ++it_env) | |
140 | if (match_var_in_string (*it_env, var, len)) | |
141 | break; | |
142 | ||
143 | if (it_env != m_environ_vector.end () - 1) | |
144 | { | |
145 | m_user_set_env.erase (std::string (*it_env)); | |
146 | xfree (*it_env); | |
147 | ||
148 | m_environ_vector.erase (it_env); | |
149 | } | |
150 | ||
151 | if (update_unset_list) | |
152 | m_user_unset_env.insert (std::string (var)); | |
153 | } | |
154 | ||
155 | /* See common/environ.h. */ | |
156 | ||
157 | void | |
158 | gdb_environ::unset (const char *var) | |
159 | { | |
160 | unset (var, true); | |
9a6c7d9c | 161 | } |
c906108c | 162 | |
9a6c7d9c SDJ |
163 | /* See common/environ.h. */ |
164 | ||
165 | char ** | |
166 | gdb_environ::envp () const | |
167 | { | |
168 | return const_cast<char **> (&m_environ_vector[0]); | |
c906108c | 169 | } |
0a2dde4a SDJ |
170 | |
171 | /* See common/environ.h. */ | |
172 | ||
173 | const std::set<std::string> & | |
174 | gdb_environ::user_set_env () const | |
175 | { | |
176 | return m_user_set_env; | |
177 | } | |
178 | ||
179 | const std::set<std::string> & | |
180 | gdb_environ::user_unset_env () const | |
181 | { | |
182 | return m_user_unset_env; | |
183 | } |