environment.hpp 25 KB

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