]>
Commit | Line | Data |
---|---|---|
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 | ||
7 | #ifndef BOOST_PROCESS_ENVIRONMENT_HPP_ | |
8 | #define BOOST_PROCESS_ENVIRONMENT_HPP_ | |
9 | ||
10 | #include <boost/process/detail/config.hpp> | |
11 | #include <boost/algorithm/string/split.hpp> | |
12 | #include <boost/algorithm/string/case_conv.hpp> | |
13 | #include <boost/iterator/transform_iterator.hpp> | |
14 | #include <boost/filesystem/path.hpp> | |
15 | ||
16 | #if defined(BOOST_POSIX_API) | |
17 | #include <boost/process/detail/posix/environment.hpp> | |
18 | #elif defined(BOOST_WINDOWS_API) | |
19 | #include <boost/process/detail/windows/environment.hpp> | |
20 | #endif | |
21 | ||
22 | namespace boost { namespace process { | |
23 | ||
24 | namespace detail { | |
25 | ||
26 | template<typename Char, typename Environment> | |
27 | struct const_entry | |
28 | { | |
29 | using value_type = Char ; | |
30 | using pointer = const value_type * ; | |
31 | using string_type = std::basic_string<value_type> ; | |
32 | using range = boost::iterator_range<pointer> ; | |
33 | using environment_t = Environment ; | |
34 | ||
35 | std::vector<string_type> to_vector() const | |
36 | { | |
37 | if (_data == nullptr) | |
38 | return std::vector<string_type>(); | |
39 | std::vector<string_type> data; | |
40 | auto str = string_type(_data); | |
41 | struct splitter | |
42 | { | |
43 | bool operator()(wchar_t w) const {return w == api::env_seperator<wchar_t>();} | |
44 | bool operator()(char c) const {return c == api::env_seperator<char> ();} | |
45 | } s; | |
46 | boost::split(data, _data, s); | |
f67539c2 | 47 | return data; |
b32b8144 FG |
48 | } |
49 | string_type to_string() const | |
50 | { | |
51 | if (_data != nullptr) | |
52 | return string_type(_data); | |
53 | else | |
54 | return string_type(); | |
55 | } | |
56 | string_type get_name() const {return string_type(_name.begin(), _name.end());} | |
57 | explicit const_entry(string_type&& name, pointer data, environment_t & env_) : | |
58 | _name(std::move(name)), _data(data), _env(&env_) {} | |
59 | ||
60 | explicit const_entry(string_type &&name, environment_t & env) : | |
61 | _name(std::move(name)), _data(nullptr), _env(&env) {} | |
62 | const_entry(const const_entry&) = default; | |
63 | const_entry& operator=(const const_entry&) = default; | |
64 | ||
65 | void reload() | |
66 | { | |
67 | auto p = _env->find(_name); | |
68 | if (p == _env->end()) | |
69 | _data = nullptr; | |
70 | else | |
71 | _data = p->_data; | |
72 | this->_env->reload(); | |
73 | ||
74 | } | |
75 | bool empty() const | |
76 | { | |
77 | return _data == nullptr; | |
78 | } | |
79 | protected: | |
80 | string_type _name; | |
81 | pointer _data; | |
82 | environment_t * _env; | |
83 | }; | |
84 | ||
85 | template<typename Char, typename Environment> | |
86 | struct entry : const_entry<Char, Environment> | |
87 | { | |
88 | using father = const_entry<Char, Environment>; | |
89 | using value_type = typename father::value_type; | |
90 | using string_type = typename father::string_type; | |
91 | using pointer = typename father::pointer; | |
92 | using environment_t = typename father::environment_t; | |
93 | ||
94 | explicit entry(string_type&& name, pointer data, environment_t & env) : | |
95 | father(std::move(name), data, env) {} | |
96 | ||
92f5a8d4 TL |
97 | explicit entry(string_type &&name, environment_t & env_) : |
98 | father(std::move(name), env_) {} | |
b32b8144 FG |
99 | |
100 | entry(const entry&) = default; | |
101 | entry& operator=(const entry&) = default; | |
102 | ||
103 | void assign(const string_type &value) | |
104 | { | |
105 | this->_env->set(this->_name, value); | |
106 | this->reload(); | |
107 | } | |
108 | void assign(const std::vector<string_type> &value) | |
109 | { | |
110 | string_type data; | |
111 | for (auto &v : value) | |
112 | { | |
113 | if (&v != &value.front()) | |
114 | data += api::env_seperator<value_type>(); | |
115 | data += v; | |
116 | } | |
117 | this->_env->set(this->_name, data); | |
118 | this->reload(); | |
119 | ||
120 | } | |
121 | void assign(const std::initializer_list<string_type> &value) | |
122 | { | |
123 | string_type data; | |
124 | for (auto &v : value) | |
125 | { | |
126 | if (&v != &*value.begin()) | |
127 | data += api::env_seperator<value_type>(); | |
128 | data += v; | |
129 | } | |
130 | this->_env->set(this->_name, data); | |
131 | this->reload(); | |
132 | ||
133 | } | |
134 | void append(const string_type &value) | |
135 | { | |
136 | if (this->_data == nullptr) | |
137 | this->_env->set(this->_name, value); | |
138 | else | |
139 | { | |
140 | string_type st = this->_data; | |
141 | this->_env->set(this->_name, st + api::env_seperator<value_type>() + value); | |
142 | } | |
143 | ||
144 | ||
145 | this->reload(); | |
146 | ||
147 | } | |
148 | void clear() | |
149 | { | |
150 | this->_env->reset(this->_name); | |
151 | this->_env->reload(); | |
152 | this->_data = nullptr; | |
153 | } | |
154 | entry &operator=(const string_type & value) | |
155 | { | |
156 | assign(value); | |
157 | return *this; | |
158 | } | |
159 | entry &operator=(const std::vector<string_type> & value) | |
160 | { | |
161 | assign(value); | |
162 | return *this; | |
163 | } | |
164 | entry &operator=(const std::initializer_list<string_type> & value) | |
165 | { | |
166 | assign(value); | |
167 | return *this; | |
168 | } | |
169 | entry &operator+=(const string_type & value) | |
170 | { | |
171 | append(value); | |
172 | return *this; | |
173 | } | |
174 | ||
175 | }; | |
176 | ||
177 | ||
178 | ||
179 | template<typename Char, typename Environment> | |
180 | struct make_entry | |
181 | { | |
182 | ||
183 | make_entry(const make_entry&) = default; | |
184 | make_entry& operator=(const make_entry&) = default; | |
185 | ||
186 | Environment *env; | |
187 | make_entry(Environment & env) : env(&env) {}; | |
188 | entry<Char, Environment> operator()(const Char* data) const | |
189 | { | |
190 | auto p = data; | |
191 | while ((*p != equal_sign<Char>()) && (*p != null_char<Char>())) | |
192 | p++; | |
193 | auto name = std::basic_string<Char>(data, p); | |
194 | p++; //go behind equal sign | |
195 | ||
196 | return entry<Char, Environment>(std::move(name), p, *env); | |
197 | } | |
198 | }; | |
199 | ||
200 | template<typename Char, typename Environment> | |
201 | struct make_const_entry | |
202 | { | |
203 | ||
204 | make_const_entry(const make_const_entry&) = default; | |
205 | make_const_entry& operator=(const make_const_entry&) = default; | |
206 | ||
207 | Environment *env; | |
208 | make_const_entry(Environment & env) : env(&env) {}; | |
209 | const_entry<Char, Environment> operator()(const Char* data) const | |
210 | { | |
211 | auto p = data; | |
212 | while ((*p != equal_sign<Char>()) && (*p != null_char<Char>())) | |
213 | p++; | |
214 | auto name = std::basic_string<Char>(data, p); | |
215 | p++; //go behind equal sign | |
216 | ||
217 | return const_entry<Char, Environment>(std::move(name), p, *env); | |
218 | } | |
219 | }; | |
220 | ||
221 | } | |
222 | ||
223 | #if !defined (BOOST_PROCESS_DOXYGEN) | |
224 | ||
225 | template<typename Char, template <class> class Implementation = detail::api::basic_environment_impl> | |
226 | class basic_environment_impl : public Implementation<Char> | |
227 | { | |
228 | Char** _get_end() const | |
229 | { | |
230 | auto p = this->_env_impl; | |
231 | while (*p != nullptr) | |
232 | p++; | |
233 | ||
234 | return p; | |
235 | } | |
236 | public: | |
237 | using string_type = std::basic_string<Char>; | |
238 | using implementation_type = Implementation<Char>; | |
239 | using base_type = basic_environment_impl<Char, Implementation>; | |
240 | using entry_maker = detail::make_entry<Char, base_type>; | |
241 | using entry_type = detail::entry <Char, base_type>; | |
242 | using const_entry_type = detail::const_entry <Char, const base_type>; | |
243 | using const_entry_maker = detail::make_const_entry<Char, const base_type>; | |
244 | ||
245 | friend entry_type; | |
246 | friend const_entry_type; | |
247 | ||
248 | using iterator = boost::transform_iterator< entry_maker, Char**, entry_type, entry_type>; | |
249 | using const_iterator = boost::transform_iterator<const_entry_maker, Char**, const_entry_type, const_entry_type>; | |
250 | using size_type = std::size_t; | |
251 | ||
252 | iterator begin() {return iterator(this->_env_impl, entry_maker(*this));} | |
253 | const_iterator begin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));} | |
254 | const_iterator cbegin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));} | |
255 | ||
256 | iterator end() {return iterator(_get_end(), entry_maker(*this));} | |
257 | const_iterator end() const {return const_iterator(_get_end(), const_entry_maker(*this));} | |
258 | const_iterator cend() const {return const_iterator(_get_end(), const_entry_maker(*this));} | |
259 | ||
260 | iterator find( const string_type& key ) | |
261 | { | |
262 | auto p = this->_env_impl; | |
263 | auto st1 = key + ::boost::process::detail::equal_sign<Char>(); | |
264 | while (*p != nullptr) | |
265 | { | |
266 | if (std::equal(st1.begin(), st1.end(), *p)) | |
267 | break; | |
268 | p++; | |
269 | } | |
270 | return iterator(p, entry_maker(*this)); | |
271 | } | |
272 | const_iterator find( const string_type& key ) const | |
273 | { | |
274 | auto p = this->_env_impl; | |
275 | auto st1 = key + ::boost::process::detail::equal_sign<Char>(); | |
276 | while (*p != nullptr) | |
277 | { | |
278 | if (std::equal(st1.begin(), st1.end(), *p)) | |
279 | break; | |
280 | p++; | |
281 | } | |
282 | return const_iterator(p, const_entry_maker(*this)); | |
283 | } | |
284 | ||
285 | std::size_t count(const string_type & st) const | |
286 | { | |
287 | auto p = this->_env_impl; | |
288 | auto st1 = st + ::boost::process::detail::equal_sign<Char>(); | |
289 | while (*p != nullptr) | |
290 | { | |
291 | if (std::equal(st1.begin(), st1.end(), *p)) | |
292 | return 1u; | |
293 | p++; | |
294 | } | |
295 | return 0u; | |
296 | } | |
297 | void erase(const string_type & id) | |
298 | { | |
299 | implementation_type::reset(id); | |
300 | this->reload(); | |
301 | } | |
302 | std::pair<iterator,bool> emplace(const string_type & id, const string_type & value) | |
303 | { | |
304 | auto f = find(id); | |
305 | if (f == end()) | |
306 | { | |
307 | implementation_type::set(id, value); | |
308 | this->reload(); | |
309 | return std::pair<iterator, bool>(find(id), true); | |
310 | } | |
311 | else | |
312 | return std::pair<iterator, bool>(f, false); | |
313 | } | |
314 | using implementation_type::implementation_type; | |
315 | using implementation_type::operator=; | |
316 | using native_handle_type = typename implementation_type::native_handle_type; | |
317 | using implementation_type::native_handle; | |
318 | //copy ctor if impl is copy-constructible | |
319 | bool empty() | |
320 | { | |
321 | return *this->_env_impl == nullptr; | |
322 | } | |
323 | std::size_t size() const | |
324 | { | |
325 | return (_get_end() - this->_env_impl); | |
326 | } | |
327 | void clear() | |
328 | { | |
329 | std::vector<string_type> names; | |
330 | names.resize(size()); | |
331 | std::transform(cbegin(), cend(), names.begin(), [](const const_entry_type & cet){return cet.get_name();}); | |
332 | ||
333 | for (auto & nm : names) | |
334 | implementation_type::reset(nm); | |
335 | ||
336 | this->reload(); | |
337 | } | |
338 | ||
339 | entry_type at( const string_type& key ) | |
340 | { | |
341 | auto f = find(key); | |
342 | if (f== end()) | |
343 | throw std::out_of_range(key + " not found"); | |
344 | return *f; | |
345 | } | |
346 | const_entry_type at( const string_type& key ) const | |
347 | { | |
348 | auto f = find(key); | |
349 | if (f== end()) | |
350 | throw std::out_of_range(key + " not found"); | |
351 | return *f; | |
352 | } | |
353 | entry_type operator[](const string_type & key) | |
354 | { | |
355 | auto p = find(key); | |
356 | if (p != end()) | |
357 | return *p; | |
358 | ||
359 | return entry_type(string_type(key), *this); | |
360 | } | |
361 | }; | |
362 | #endif | |
363 | ||
364 | #if defined(BOOST_PROCESS_DOXYGEN) | |
365 | /**Template representation of environments. It takes a character type (`char` or `wchar_t`) | |
366 | * as template parameter to implement the environment | |
367 | */ | |
368 | template<typename Char> | |
369 | class basic_environment | |
370 | { | |
371 | ||
372 | public: | |
373 | typedef std::basic_string<Char> string_type; | |
374 | typedef boost::transform_iterator< entry_maker, Char**> iterator ; | |
375 | typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ; | |
376 | typedef std::size_t size_type ; | |
377 | ||
378 | iterator begin() ; ///<Returns an iterator to the beginning | |
379 | const_iterator begin() const ; ///<Returns an iterator to the beginning | |
380 | const_iterator cbegin() const ; ///<Returns an iterator to the beginning | |
381 | ||
382 | iterator end() ; ///<Returns an iterator to the end | |
383 | const_iterator end() const; ///<Returns an iterator to the end | |
384 | const_iterator cend() const; ///<Returns an iterator to the end | |
385 | ||
386 | iterator find( const string_type& key ); ///<Find a variable by its name | |
387 | const_iterator find( const string_type& key ) const; ///<Find a variable by its name | |
388 | ||
389 | std::size_t count(const string_type & st) const; ///<Number of variables | |
390 | void erase(const string_type & id); ///<Erase variable by id. | |
391 | ///Emplace an environment variable. | |
392 | std::pair<iterator,bool> emplace(const string_type & id, const string_type & value); | |
393 | ||
394 | ///Default constructor | |
395 | basic_environment(); | |
396 | ///Copy constructor. | |
397 | basic_environment(const basic_environment & ); | |
398 | ///Move constructor. | |
399 | basic_environment(basic_environment && ); | |
400 | ||
401 | ///Copy assignment. | |
402 | basic_environment& operator=(const basic_environment & ); | |
403 | ///Move assignment. | |
404 | basic_environment& operator=(basic_environment && ); | |
405 | ||
406 | typedef typename detail::implementation_type::native_handle_type native_handle; | |
407 | ||
408 | ///Check if environment has entries. | |
409 | bool empty(); | |
410 | ///Get the number of variables. | |
411 | std::size_t size() const; | |
412 | ///Clear the environment. @attention Use with care, passed environment cannot be empty. | |
413 | void clear(); | |
414 | ///Get the entry with the key. Throws if it does not exist. | |
415 | entry_type at( const string_type& key ); | |
416 | ///Get the entry with the key. Throws if it does not exist. | |
417 | const_entry_type at( const string_type& key ) const; | |
418 | ///Get the entry with the given key. It creates the entry if it doesn't exist. | |
419 | entry_type operator[](const string_type & key); | |
420 | ||
421 | /**Proxy class used for read access to members by [] or .at() | |
422 | * @attention Holds a reference to the environment it was created from. | |
423 | */ | |
424 | template<typename Char, typename Environment> | |
425 | struct const_entry_type | |
426 | { | |
427 | typedef Char value_type; | |
428 | typedef const value_type * pointer; | |
429 | typedef std::basic_string<value_type> string_type; | |
430 | typedef boost::iterator_range<pointer> range; | |
431 | typedef Environment environment_t; | |
432 | ||
433 | ///Split the entry by ";" or ":" and return it as a vector. Used by PATH. | |
434 | std::vector<string_type> to_vector() const | |
435 | ///Get the value as string. | |
436 | string_type to_string() const | |
437 | ///Get the name of this entry. | |
438 | string_type get_name() const {return string_type(_name.begin(), _name.end());} | |
439 | ///Copy Constructor | |
440 | const_entry(const const_entry&) = default; | |
441 | ///Move Constructor | |
442 | const_entry& operator=(const const_entry&) = default; | |
443 | ///Check if the entry is empty. | |
444 | bool empty() const; | |
445 | }; | |
446 | ||
447 | /**Proxy class used for read and write access to members by [] or .at() | |
448 | * @attention Holds a reference to the environment it was created from. | |
449 | */ | |
450 | template<typename Char, typename Environment> | |
451 | struct entry_type | |
452 | { | |
453 | ||
454 | typedef Char value_type; | |
455 | typedef const value_type * pointer; | |
456 | typedef std::basic_string<value_type> string_type; | |
457 | typedef boost::iterator_range<pointer> range; | |
458 | typedef Environment environment_t; | |
459 | ||
460 | ///Split the entry by ";" or ":" and return it as a vector. Used by PATH. | |
461 | std::vector<string_type> to_vector() const | |
462 | ///Get the value as string. | |
463 | string_type to_string() const | |
464 | ///Get the name of this entry. | |
465 | string_type get_name() const {return string_type(_name.begin(), _name.end());} | |
466 | ///Copy Constructor | |
467 | entry(const entry&) = default; | |
468 | ///Move Constructor | |
469 | entry& operator=(const entry&) = default; | |
470 | ///Check if the entry is empty. | |
471 | bool empty() const; | |
472 | ||
473 | ///Assign a string to the value | |
474 | void assign(const string_type &value); | |
475 | ///Assign a set of strings to the entry; they will be separated by ';' or ':'. | |
476 | void assign(const std::vector<string_type> &value); | |
477 | ///Append a string to the end of the entry, it will separated by ';' or ':'. | |
478 | void append(const string_type &value); | |
479 | ///Reset the value | |
480 | void clear(); | |
481 | ///Assign a string to the entry. | |
482 | entry &operator=(const string_type & value); | |
483 | ///Assign a set of strings to the entry; they will be separated by ';' or ':'. | |
484 | entry &operator=(const std::vector<string_type> & value); | |
485 | ///Append a string to the end of the entry, it will separated by ';' or ':'. | |
486 | entry &operator+=(const string_type & value); | |
487 | }; | |
488 | ||
489 | }; | |
490 | ||
491 | /**Template representation of the environment of this process. It takes a template | |
492 | * as template parameter to implement the environment. All instances of this class | |
493 | * refer to the same environment, but might not get updated if another one makes changes. | |
494 | */ | |
495 | template<typename Char> | |
496 | class basic_native_environment | |
497 | { | |
498 | ||
499 | public: | |
500 | typedef std::basic_string<Char> string_type; | |
501 | typedef boost::transform_iterator< entry_maker, Char**> iterator ; | |
502 | typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ; | |
503 | typedef std::size_t size_type ; | |
504 | ||
505 | iterator begin() ; ///<Returns an iterator to the beginning | |
506 | const_iterator begin() const ; ///<Returns an iterator to the beginning | |
507 | const_iterator cbegin() const ; ///<Returns an iterator to the beginning | |
508 | ||
509 | iterator end() ; ///<Returns an iterator to the end | |
510 | const_iterator end() const; ///<Returns an iterator to the end | |
511 | const_iterator cend() const; ///<Returns an iterator to the end | |
512 | ||
513 | iterator find( const string_type& key ); ///<Find a variable by its name | |
514 | const_iterator find( const string_type& key ) const; ///<Find a variable by its name | |
515 | ||
516 | std::size_t count(const string_type & st) const; ///<Number of variables | |
517 | void erase(const string_type & id); ///<Erase variable by id. | |
518 | ///Emplace an environment variable. | |
519 | std::pair<iterator,bool> emplace(const string_type & id, const string_type & value); | |
520 | ||
521 | ///Default constructor | |
522 | basic_native_environment(); | |
523 | ///Move constructor. | |
524 | basic_native_environment(basic_native_environment && ); | |
525 | ///Move assignment. | |
526 | basic_native_environment& operator=(basic_native_environment && ); | |
527 | ||
528 | typedef typename detail::implementation_type::native_handle_type native_handle; | |
529 | ||
530 | ///Check if environment has entries. | |
531 | bool empty(); | |
532 | ///Get the number of variables. | |
533 | std::size_t size() const; | |
534 | ///Get the entry with the key. Throws if it does not exist. | |
535 | entry_type at( const string_type& key ); | |
536 | ///Get the entry with the key. Throws if it does not exist. | |
537 | const_entry_type at( const string_type& key ) const; | |
538 | ///Get the entry with the given key. It creates the entry if it doesn't exist. | |
539 | entry_type operator[](const string_type & key); | |
540 | ||
541 | /**Proxy class used for read access to members by [] or .at() | |
542 | * @attention Holds a reference to the environment it was created from. | |
543 | */ | |
544 | template<typename Char, typename Environment> | |
545 | struct const_entry_type | |
546 | { | |
547 | typedef Char value_type; | |
548 | typedef const value_type * pointer; | |
549 | typedef std::basic_string<value_type> string_type; | |
550 | typedef boost::iterator_range<pointer> range; | |
551 | typedef Environment environment_t; | |
552 | ||
553 | ///Split the entry by ";" or ":" and return it as a vector. Used by PATH. | |
554 | std::vector<string_type> to_vector() const | |
555 | ///Get the value as string. | |
556 | string_type to_string() const | |
557 | ///Get the name of this entry. | |
558 | string_type get_name() const {return string_type(_name.begin(), _name.end());} | |
559 | ///Copy Constructor | |
560 | const_entry(const const_entry&) = default; | |
561 | ///Move Constructor | |
562 | const_entry& operator=(const const_entry&) = default; | |
563 | ///Check if the entry is empty. | |
564 | bool empty() const; | |
565 | }; | |
566 | ||
567 | /**Proxy class used for read and write access to members by [] or .at() | |
568 | * @attention Holds a reference to the environment it was created from. | |
569 | */ | |
570 | template<typename Char, typename Environment> | |
571 | struct entry_type | |
572 | { | |
573 | ||
574 | typedef Char value_type; | |
575 | typedef const value_type * pointer; | |
576 | typedef std::basic_string<value_type> string_type; | |
577 | typedef boost::iterator_range<pointer> range; | |
578 | typedef Environment environment_t; | |
579 | ||
580 | ///Split the entry by ";" or ":" and return it as a vector. Used by PATH. | |
581 | std::vector<string_type> to_vector() const | |
582 | ///Get the value as string. | |
583 | string_type to_string() const | |
584 | ///Get the name of this entry. | |
585 | string_type get_name() const {return string_type(_name.begin(), _name.end());} | |
586 | ///Copy Constructor | |
587 | entry(const entry&) = default; | |
588 | ///Move Constructor | |
589 | entry& operator=(const entry&) = default; | |
590 | ///Check if the entry is empty. | |
591 | bool empty() const; | |
592 | ||
593 | ///Assign a string to the value | |
594 | void assign(const string_type &value); | |
595 | ///Assign a set of strings to the entry; they will be separated by ';' or ':'. | |
596 | void assign(const std::vector<string_type> &value); | |
597 | ///Append a string to the end of the entry, it will separated by ';' or ':'. | |
598 | void append(const string_type &value); | |
599 | ///Reset the value | |
600 | void clear(); | |
601 | ///Assign a string to the entry. | |
602 | entry &operator=(const string_type & value); | |
603 | ///Assign a set of strings to the entry; they will be separated by ';' or ':'. | |
604 | entry &operator=(const std::vector<string_type> & value); | |
605 | ///Append a string to the end of the entry, it will separated by ';' or ':'. | |
606 | entry &operator+=(const string_type & value); | |
607 | }; | |
608 | ||
609 | }; | |
610 | ||
611 | #endif | |
612 | ||
613 | ///Definition of the environment for the current process. | |
614 | template<typename Char> | |
615 | class basic_native_environment : public basic_environment_impl<Char, detail::api::native_environment_impl> | |
616 | { | |
617 | public: | |
618 | using base_type = basic_environment_impl<Char, detail::api::native_environment_impl>; | |
619 | using base_type::base_type; | |
620 | using base_type::operator=; | |
621 | }; | |
622 | ||
623 | ///Type definition to hold a seperate environment. | |
624 | template<typename Char> | |
625 | class basic_environment : public basic_environment_impl<Char, detail::api::basic_environment_impl> | |
626 | { | |
627 | public: | |
628 | using base_type = basic_environment_impl<Char, detail::api::basic_environment_impl>; | |
629 | using base_type::base_type; | |
630 | using base_type::operator=; | |
631 | }; | |
632 | ||
633 | ||
11fdf7f2 | 634 | #if !defined(BOOST_NO_ANSI_APIS) |
b32b8144 FG |
635 | ///Definition of the environment for the current process. |
636 | typedef basic_native_environment<char> native_environment; | |
11fdf7f2 | 637 | #endif |
b32b8144 FG |
638 | ///Definition of the environment for the current process. |
639 | typedef basic_native_environment<wchar_t> wnative_environment; | |
640 | ||
11fdf7f2 | 641 | #if !defined(BOOST_NO_ANSI_APIS) |
b32b8144 FG |
642 | ///Type definition to hold a seperate environment. |
643 | typedef basic_environment<char> environment; | |
11fdf7f2 | 644 | #endif |
b32b8144 FG |
645 | ///Type definition to hold a seperate environment. |
646 | typedef basic_environment<wchar_t> wenvironment; | |
647 | ||
648 | } | |
649 | ||
650 | ///Namespace containing information of the calling process. | |
651 | namespace this_process | |
652 | { | |
653 | ||
654 | ///Definition of the native handle type. | |
655 | typedef ::boost::process::detail::api::native_handle_t native_handle_type; | |
656 | ||
11fdf7f2 | 657 | #if !defined(BOOST_NO_ANSI_APIS) |
b32b8144 FG |
658 | ///Definition of the environment for this process. |
659 | using ::boost::process::native_environment; | |
11fdf7f2 | 660 | #endif |
b32b8144 FG |
661 | ///Definition of the environment for this process. |
662 | using ::boost::process::wnative_environment; | |
663 | ||
664 | ///Get the process id of the current process. | |
665 | inline int get_id() { return ::boost::process::detail::api::get_id();} | |
666 | ///Get the native handle of the current process. | |
667 | inline native_handle_type native_handle() { return ::boost::process::detail::api::native_handle();} | |
11fdf7f2 | 668 | #if !defined(BOOST_NO_ANSI_APIS) |
b32b8144 FG |
669 | ///Get the enviroment of the current process. |
670 | inline native_environment environment() { return ::boost::process:: native_environment(); } | |
11fdf7f2 | 671 | #endif |
b32b8144 FG |
672 | ///Get the enviroment of the current process. |
673 | inline wnative_environment wenvironment() { return ::boost::process::wnative_environment(); } | |
674 | ///Get the path environment variable of the current process runs. | |
675 | inline std::vector<boost::filesystem::path> path() | |
676 | { | |
677 | #if defined(BOOST_WINDOWS_API) | |
678 | const ::boost::process::wnative_environment ne{}; | |
679 | typedef typename ::boost::process::wnative_environment::const_entry_type value_type; | |
20effc67 | 680 | static constexpr auto id = L"PATH"; |
b32b8144 FG |
681 | #else |
682 | const ::boost::process::native_environment ne{}; | |
683 | typedef typename ::boost::process::native_environment::const_entry_type value_type; | |
20effc67 | 684 | static constexpr auto id = "PATH"; |
b32b8144 FG |
685 | #endif |
686 | ||
687 | auto itr = std::find_if(ne.cbegin(), ne.cend(), | |
688 | [&](const value_type & e) | |
689 | {return id == ::boost::to_upper_copy(e.get_name(), ::boost::process::detail::process_locale());}); | |
690 | ||
691 | if (itr == ne.cend()) | |
692 | return {}; | |
693 | ||
694 | auto vec = itr->to_vector(); | |
695 | ||
696 | std::vector<boost::filesystem::path> val; | |
697 | val.resize(vec.size()); | |
698 | ||
699 | std::copy(vec.begin(), vec.end(), val.begin()); | |
700 | ||
701 | return val; | |
702 | } | |
703 | } | |
704 | } | |
705 | #endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENVIRONMENT_HPP_ */ |