]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/process/detail/posix/environment.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / process / detail / posix / environment.hpp
CommitLineData
b32b8144
FG
1// Copyright (c) 2016 Klemens D. Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_
7#define BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_
8
9#include <string>
10#include <vector>
11#include <unordered_map>
12#include <boost/process/detail/config.hpp>
13#include <algorithm>
14#include <cstdlib>
15#include <boost/process/locale.hpp>
16
17
18namespace boost { namespace process { namespace detail { namespace posix {
19
20template<typename Char>
21class native_environment_impl
22{
23 static std::vector<std::basic_string<Char>> _load()
24 {
25 std::vector<std::basic_string<Char>> val;
26 auto p = environ;
27 while (*p != nullptr)
28 {
29 std::string str = *p;
30 val.push_back(::boost::process::detail::convert(str));
31 p++;
32 }
33 return val;
34 }
35 static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & vec)
36 {
37 std::vector<Char*> val;
38 val.resize(vec.size() + 1);
39 std::transform(vec.begin(), vec.end(), val.begin(),
40 [](std::basic_string<Char> & str)
41 {
42 return &str.front();
43 });
44 val.back() = nullptr;
45 return val;
46 }
47 std::vector<std::basic_string<Char>> _buffer = _load();
48 std::vector<Char*> _impl = _load_var(_buffer);
49public:
50 using char_type = Char;
51 using pointer_type = const char_type*;
52 using string_type = std::basic_string<char_type>;
53 using native_handle_type = char_type **;
54
55 void reload()
56 {
57 _buffer = _load();
58 _impl = _load_var(_buffer);
59 }
60
61 string_type get(const pointer_type id) { return get(string_type(id)); }
62 void set(const pointer_type id, const pointer_type value)
63 {
64 set(string_type(id), string_type(value));
65 }
66 void reset(const pointer_type id) { reset(string_type(id)); }
67
68 string_type get(const string_type & id)
69 {
70 std::string id_c = ::boost::process::detail::convert(id);
71 std::string g = ::getenv(id_c.c_str());
72 return ::boost::process::detail::convert(g.c_str());
73 }
74 void set(const string_type & id, const string_type & value)
75 {
76 std::string id_c = ::boost::process::detail::convert(id.c_str());
77 std::string value_c = ::boost::process::detail::convert(value.c_str());
78 auto res = ::setenv(id_c.c_str(), value_c.c_str(), true);
79 if (res != 0)
80 boost::process::detail::throw_last_error();
81 }
82 void reset(const string_type & id)
83 {
84 std::string id_c = ::boost::process::detail::convert(id.c_str());
85 auto res = ::unsetenv(id_c.c_str());
86 if (res != 0)
87 ::boost::process::detail::throw_last_error();
88 }
89
90 native_environment_impl() = default;
91 native_environment_impl(const native_environment_impl& ) = delete;
92 native_environment_impl(native_environment_impl && ) = default;
93 native_environment_impl & operator=(const native_environment_impl& ) = delete;
94 native_environment_impl & operator=(native_environment_impl && ) = default;
95 native_handle_type _env_impl = _impl.data();
96
f67539c2 97 native_handle_type native_handle() const {return _env_impl;}
b32b8144
FG
98};
99
100template<>
101class native_environment_impl<char>
102{
103public:
104 using char_type = char;
105 using pointer_type = const char_type*;
106 using string_type = std::basic_string<char_type>;
107 using native_handle_type = char_type **;
108
109 void reload() {this->_env_impl = ::environ;}
110
111 string_type get(const pointer_type id) { return getenv(id); }
112 void set(const pointer_type id, const pointer_type value)
113 {
114 auto res = ::setenv(id, value, 1);
115 if (res != 0)
116 boost::process::detail::throw_last_error();
117 reload();
118 }
119 void reset(const pointer_type id)
120 {
121 auto res = ::unsetenv(id);
122 if (res != 0)
123 boost::process::detail::throw_last_error();
124 reload();
125 }
126
127 string_type get(const string_type & id) {return get(id.c_str());}
128 void set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); }
129 void reset(const string_type & id) {reset(id.c_str());}
130
131 native_environment_impl() = default;
132 native_environment_impl(const native_environment_impl& ) = delete;
133 native_environment_impl(native_environment_impl && ) = default;
134 native_environment_impl & operator=(const native_environment_impl& ) = delete;
135 native_environment_impl & operator=(native_environment_impl && ) = default;
136 native_handle_type _env_impl = environ;
137
138 native_handle_type native_handle() const {return ::environ;}
139};
140
141
142
143template<typename Char>
144struct basic_environment_impl
145{
146 std::vector<std::basic_string<Char>> _data {};
147 static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & data);
148 std::vector<Char*> _env_arr{_load_var(_data)};
149public:
150 using char_type = Char;
151 using pointer_type = const char_type*;
152 using string_type = std::basic_string<char_type>;
153 using native_handle_type = Char**;
154 void reload()
155 {
156 _env_arr = _load_var(_data);
157 _env_impl = _env_arr.data();
158 }
159
160 string_type get(const pointer_type id) {return get(string_type(id));}
161 void set(const pointer_type id, const pointer_type value) {set(string_type(id), value);}
162 void reset(const pointer_type id) {reset(string_type(id));}
163
164 string_type get(const string_type & id);
165 void set(const string_type & id, const string_type & value);
166 void reset(const string_type & id);
167
168 basic_environment_impl(const native_environment_impl<Char> & nei);
169 basic_environment_impl() = default;
170 basic_environment_impl(const basic_environment_impl& rhs)
171 : _data(rhs._data)
172 {
173
174 }
175 basic_environment_impl(basic_environment_impl && ) = default;
176 basic_environment_impl & operator=(const basic_environment_impl& rhs)
177 {
178 _data = rhs._data;
179 _env_arr = _load_var(_data);
180 _env_impl = &*_env_arr.begin();
181 return *this;
182 }
183 basic_environment_impl & operator=(basic_environment_impl && ) = default;
184
185 template<typename CharR>
186 explicit inline basic_environment_impl(
187 const basic_environment_impl<CharR>& rhs,
188 const ::boost::process::codecvt_type & cv = ::boost::process::codecvt())
189 : _data(rhs._data.size())
190 {
191 std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
192 [&](const std::basic_string<CharR> & st)
193 {
194 return ::boost::process::detail::convert(st, cv);
195 }
196
197 );
198 reload();
199 }
200
201 template<typename CharR>
202 basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
203 {
204 _data = ::boost::process::detail::convert(rhs._data);
205 _env_arr = _load_var(&*_data.begin());
206 _env_impl = &*_env_arr.begin();
207 return *this;
208 }
209
210 Char ** _env_impl = &*_env_arr.data();
211
212 native_handle_type native_handle() const {return &_data.front();}
213};
214
215
216template<typename Char>
217basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei)
218{
219 auto beg = nei.native_handle();
220
221 auto end = beg;
222 while (*end != nullptr)
223 end++;
224 this->_data.assign(beg, end);
225 reload();
226}
227
228
229template<typename Char>
230inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
231{
232 auto itr = std::find_if(_data.begin(), _data.end(),
20effc67 233 [&](const string_type & st) -> bool
b32b8144
FG
234 {
235 if (st.size() <= id.size())
236 return false;
237 return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
238 }
239 );
240
241 if (itr == _data.end())
242 {
243 return "";
244 }
245 else return
246 itr->data() + id.size(); //id=Thingy -> +2 points to T
247}
248
249template<typename Char>
250inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
251{
252 auto itr = std::find_if(_data.begin(), _data.end(),
20effc67 253 [&](const string_type & st) -> bool
b32b8144
FG
254 {
255 if (st.size() <= id.size())
256 return false;
257 return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
258 }
259 );
260
261 if (itr != _data.end())
262 *itr = id + equal_sign<Char>() + value;
263 else
264 _data.push_back(id + equal_sign<Char>() + value);
265
266 reload();
267}
268
269template<typename Char>
270inline void basic_environment_impl<Char>::reset(const string_type &id)
271{
272 auto itr = std::find_if(_data.begin(), _data.end(),
20effc67 273 [&](const string_type & st) -> bool
b32b8144
FG
274 {
275 if (st.size() <= id.size())
276 return false;
277 return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
278 }
279 );
280 if (itr != _data.end())
281 {
282 _data.erase(itr);//and remove it
283 }
284
285 reload();
286
287
288}
289
290template<typename Char>
291std::vector<Char*> basic_environment_impl<Char>::_load_var(std::vector<std::basic_string<Char>> & data)
292{
293 std::vector<Char*> ret;
294 ret.reserve(data.size() +1);
295
296 for (auto & val : data)
f67539c2
TL
297 {
298 if (val.empty())
299 val.push_back(0);
b32b8144 300 ret.push_back(&val.front());
f67539c2 301 }
b32b8144
FG
302
303 ret.push_back(nullptr);
304 return ret;
305}
306
307template<typename T> constexpr T env_seperator();
308template<> constexpr char env_seperator() {return ':'; }
309template<> constexpr wchar_t env_seperator() {return L':'; }
310
311
312typedef int native_handle_t;
313
314inline int get_id() {return getpid(); }
315inline int native_handle() {return getpid(); }
316
317}
318
319}
320}
321}
322
323
324
325
326#endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */