environment.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  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/filesystem/path.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. if (std::equal(st1.begin(), st1.end(), *p))
  226. break;
  227. p++;
  228. }
  229. return iterator(p, entry_maker(*this));
  230. }
  231. const_iterator find( const string_type& key ) const
  232. {
  233. auto p = this->_env_impl;
  234. auto st1 = key + ::boost::process::detail::equal_sign<Char>();
  235. while (*p != nullptr)
  236. {
  237. if (std::equal(st1.begin(), st1.end(), *p))
  238. break;
  239. p++;
  240. }
  241. return const_iterator(p, const_entry_maker(*this));
  242. }
  243. std::size_t count(const string_type & st) const
  244. {
  245. auto p = this->_env_impl;
  246. auto st1 = st + ::boost::process::detail::equal_sign<Char>();
  247. while (*p != nullptr)
  248. {
  249. if (std::equal(st1.begin(), st1.end(), *p))
  250. return 1u;
  251. p++;
  252. }
  253. return 0u;
  254. }
  255. void erase(const string_type & id)
  256. {
  257. implementation_type::reset(id);
  258. this->reload();
  259. }
  260. std::pair<iterator,bool> emplace(const string_type & id, const string_type & value)
  261. {
  262. auto f = find(id);
  263. if (f == end())
  264. {
  265. implementation_type::set(id, value);
  266. this->reload();
  267. return std::pair<iterator, bool>(find(id), true);
  268. }
  269. else
  270. return std::pair<iterator, bool>(f, false);
  271. }
  272. using implementation_type::implementation_type;
  273. using implementation_type::operator=;
  274. using native_handle_type = typename implementation_type::native_handle_type;
  275. using implementation_type::native_handle;
  276. //copy ctor if impl is copy-constructible
  277. bool empty()
  278. {
  279. return *this->_env_impl == nullptr;
  280. }
  281. std::size_t size() const
  282. {
  283. return (_get_end() - this->_env_impl);
  284. }
  285. void clear()
  286. {
  287. std::vector<string_type> names;
  288. names.resize(size());
  289. std::transform(cbegin(), cend(), names.begin(), [](const const_entry_type & cet){return cet.get_name();});
  290. for (auto & nm : names)
  291. implementation_type::reset(nm);
  292. this->reload();
  293. }
  294. entry_type at( const string_type& key )
  295. {
  296. auto f = find(key);
  297. if (f== end())
  298. throw std::out_of_range(key + " not found");
  299. return *f;
  300. }
  301. const_entry_type at( const string_type& key ) const
  302. {
  303. auto f = find(key);
  304. if (f== end())
  305. throw std::out_of_range(key + " not found");
  306. return *f;
  307. }
  308. entry_type operator[](const string_type & key)
  309. {
  310. auto p = find(key);
  311. if (p != end())
  312. return *p;
  313. return entry_type(string_type(key), *this);
  314. }
  315. };
  316. #endif
  317. #if defined(BOOST_PROCESS_DOXYGEN)
  318. /**Template representation of environments. It takes a character type (`char` or `wchar_t`)
  319. * as template parameter to implement the environment
  320. */
  321. template<typename Char>
  322. class basic_environment
  323. {
  324. public:
  325. typedef std::basic_string<Char> string_type;
  326. typedef boost::transform_iterator< entry_maker, Char**> iterator ;
  327. typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
  328. typedef std::size_t size_type ;
  329. iterator begin() ; ///<Returns an iterator to the beginning
  330. const_iterator begin() const ; ///<Returns an iterator to the beginning
  331. const_iterator cbegin() const ; ///<Returns an iterator to the beginning
  332. iterator end() ; ///<Returns an iterator to the end
  333. const_iterator end() const; ///<Returns an iterator to the end
  334. const_iterator cend() const; ///<Returns an iterator to the end
  335. iterator find( const string_type& key ); ///<Find a variable by its name
  336. const_iterator find( const string_type& key ) const; ///<Find a variable by its name
  337. std::size_t count(const string_type & st) const; ///<Number of variables
  338. void erase(const string_type & id); ///<Erase variable by id.
  339. ///Emplace an environment variable.
  340. std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
  341. ///Default constructor
  342. basic_environment();
  343. ///Copy constructor.
  344. basic_environment(const basic_environment & );
  345. ///Move constructor.
  346. basic_environment(basic_environment && );
  347. ///Copy assignment.
  348. basic_environment& operator=(const basic_environment & );
  349. ///Move assignment.
  350. basic_environment& operator=(basic_environment && );
  351. typedef typename detail::implementation_type::native_handle_type native_handle;
  352. ///Check if environment has entries.
  353. bool empty();
  354. ///Get the number of variables.
  355. std::size_t size() const;
  356. ///Clear the environment. @attention Use with care, passed environment cannot be empty.
  357. void clear();
  358. ///Get the entry with the key. Throws if it does not exist.
  359. entry_type at( const string_type& key );
  360. ///Get the entry with the key. Throws if it does not exist.
  361. const_entry_type at( const string_type& key ) const;
  362. ///Get the entry with the given key. It creates the entry if it doesn't exist.
  363. entry_type operator[](const string_type & key);
  364. /**Proxy class used for read access to members by [] or .at()
  365. * @attention Holds a reference to the environment it was created from.
  366. */
  367. template<typename Char, typename Environment>
  368. struct const_entry_type
  369. {
  370. typedef Char value_type;
  371. typedef const value_type * pointer;
  372. typedef std::basic_string<value_type> string_type;
  373. typedef boost::iterator_range<pointer> range;
  374. typedef Environment environment_t;
  375. ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
  376. std::vector<string_type> to_vector() const
  377. ///Get the value as string.
  378. string_type to_string() const
  379. ///Get the name of this entry.
  380. string_type get_name() const {return string_type(_name.begin(), _name.end());}
  381. ///Copy Constructor
  382. const_entry(const const_entry&) = default;
  383. ///Move Constructor
  384. const_entry& operator=(const const_entry&) = default;
  385. ///Check if the entry is empty.
  386. bool empty() const;
  387. };
  388. /**Proxy class used for read and write access to members by [] or .at()
  389. * @attention Holds a reference to the environment it was created from.
  390. */
  391. template<typename Char, typename Environment>
  392. struct entry_type
  393. {
  394. typedef Char value_type;
  395. typedef const value_type * pointer;
  396. typedef std::basic_string<value_type> string_type;
  397. typedef boost::iterator_range<pointer> range;
  398. typedef Environment environment_t;
  399. ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
  400. std::vector<string_type> to_vector() const
  401. ///Get the value as string.
  402. string_type to_string() const
  403. ///Get the name of this entry.
  404. string_type get_name() const {return string_type(_name.begin(), _name.end());}
  405. ///Copy Constructor
  406. entry(const entry&) = default;
  407. ///Move Constructor
  408. entry& operator=(const entry&) = default;
  409. ///Check if the entry is empty.
  410. bool empty() const;
  411. ///Assign a string to the value
  412. void assign(const string_type &value);
  413. ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
  414. void assign(const std::vector<string_type> &value);
  415. ///Append a string to the end of the entry, it will separated by ';' or ':'.
  416. void append(const string_type &value);
  417. ///Reset the value
  418. void clear();
  419. ///Assign a string to the entry.
  420. entry &operator=(const string_type & value);
  421. ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
  422. entry &operator=(const std::vector<string_type> & value);
  423. ///Append a string to the end of the entry, it will separated by ';' or ':'.
  424. entry &operator+=(const string_type & value);
  425. };
  426. };
  427. /**Template representation of the environment of this process. It takes a template
  428. * as template parameter to implement the environment. All instances of this class
  429. * refer to the same environment, but might not get updated if another one makes changes.
  430. */
  431. template<typename Char>
  432. class basic_native_environment
  433. {
  434. public:
  435. typedef std::basic_string<Char> string_type;
  436. typedef boost::transform_iterator< entry_maker, Char**> iterator ;
  437. typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
  438. typedef std::size_t size_type ;
  439. iterator begin() ; ///<Returns an iterator to the beginning
  440. const_iterator begin() const ; ///<Returns an iterator to the beginning
  441. const_iterator cbegin() const ; ///<Returns an iterator to the beginning
  442. iterator end() ; ///<Returns an iterator to the end
  443. const_iterator end() const; ///<Returns an iterator to the end
  444. const_iterator cend() const; ///<Returns an iterator to the end
  445. iterator find( const string_type& key ); ///<Find a variable by its name
  446. const_iterator find( const string_type& key ) const; ///<Find a variable by its name
  447. std::size_t count(const string_type & st) const; ///<Number of variables
  448. void erase(const string_type & id); ///<Erase variable by id.
  449. ///Emplace an environment variable.
  450. std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
  451. ///Default constructor
  452. basic_native_environment();
  453. ///Move constructor.
  454. basic_native_environment(basic_native_environment && );
  455. ///Move assignment.
  456. basic_native_environment& operator=(basic_native_environment && );
  457. typedef typename detail::implementation_type::native_handle_type native_handle;
  458. ///Check if environment has entries.
  459. bool empty();
  460. ///Get the number of variables.
  461. std::size_t size() const;
  462. ///Get the entry with the key. Throws if it does not exist.
  463. entry_type at( const string_type& key );
  464. ///Get the entry with the key. Throws if it does not exist.
  465. const_entry_type at( const string_type& key ) const;
  466. ///Get the entry with the given key. It creates the entry if it doesn't exist.
  467. entry_type operator[](const string_type & key);
  468. /**Proxy class used for read access to members by [] or .at()
  469. * @attention Holds a reference to the environment it was created from.
  470. */
  471. template<typename Char, typename Environment>
  472. struct const_entry_type
  473. {
  474. typedef Char value_type;
  475. typedef const value_type * pointer;
  476. typedef std::basic_string<value_type> string_type;
  477. typedef boost::iterator_range<pointer> range;
  478. typedef Environment environment_t;
  479. ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
  480. std::vector<string_type> to_vector() const
  481. ///Get the value as string.
  482. string_type to_string() const
  483. ///Get the name of this entry.
  484. string_type get_name() const {return string_type(_name.begin(), _name.end());}
  485. ///Copy Constructor
  486. const_entry(const const_entry&) = default;
  487. ///Move Constructor
  488. const_entry& operator=(const const_entry&) = default;
  489. ///Check if the entry is empty.
  490. bool empty() const;
  491. };
  492. /**Proxy class used for read and write access to members by [] or .at()
  493. * @attention Holds a reference to the environment it was created from.
  494. */
  495. template<typename Char, typename Environment>
  496. struct entry_type
  497. {
  498. typedef Char value_type;
  499. typedef const value_type * pointer;
  500. typedef std::basic_string<value_type> string_type;
  501. typedef boost::iterator_range<pointer> range;
  502. typedef Environment environment_t;
  503. ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
  504. std::vector<string_type> to_vector() const
  505. ///Get the value as string.
  506. string_type to_string() const
  507. ///Get the name of this entry.
  508. string_type get_name() const {return string_type(_name.begin(), _name.end());}
  509. ///Copy Constructor
  510. entry(const entry&) = default;
  511. ///Move Constructor
  512. entry& operator=(const entry&) = default;
  513. ///Check if the entry is empty.
  514. bool empty() const;
  515. ///Assign a string to the value
  516. void assign(const string_type &value);
  517. ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
  518. void assign(const std::vector<string_type> &value);
  519. ///Append a string to the end of the entry, it will separated by ';' or ':'.
  520. void append(const string_type &value);
  521. ///Reset the value
  522. void clear();
  523. ///Assign a string to the entry.
  524. entry &operator=(const string_type & value);
  525. ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
  526. entry &operator=(const std::vector<string_type> & value);
  527. ///Append a string to the end of the entry, it will separated by ';' or ':'.
  528. entry &operator+=(const string_type & value);
  529. };
  530. };
  531. #endif
  532. ///Definition of the environment for the current process.
  533. template<typename Char>
  534. class basic_native_environment : public basic_environment_impl<Char, detail::api::native_environment_impl>
  535. {
  536. public:
  537. using base_type = basic_environment_impl<Char, detail::api::native_environment_impl>;
  538. using base_type::base_type;
  539. using base_type::operator=;
  540. };
  541. ///Type definition to hold a seperate environment.
  542. template<typename Char>
  543. class basic_environment : public basic_environment_impl<Char, detail::api::basic_environment_impl>
  544. {
  545. public:
  546. using base_type = basic_environment_impl<Char, detail::api::basic_environment_impl>;
  547. using base_type::base_type;
  548. using base_type::operator=;
  549. };
  550. #if !defined(BOOST_NO_ANSI_APIS)
  551. ///Definition of the environment for the current process.
  552. typedef basic_native_environment<char> native_environment;
  553. #endif
  554. ///Definition of the environment for the current process.
  555. typedef basic_native_environment<wchar_t> wnative_environment;
  556. #if !defined(BOOST_NO_ANSI_APIS)
  557. ///Type definition to hold a seperate environment.
  558. typedef basic_environment<char> environment;
  559. #endif
  560. ///Type definition to hold a seperate environment.
  561. typedef basic_environment<wchar_t> wenvironment;
  562. }
  563. ///Namespace containing information of the calling process.
  564. namespace this_process
  565. {
  566. ///Definition of the native handle type.
  567. typedef ::boost::process::detail::api::native_handle_t native_handle_type;
  568. #if !defined(BOOST_NO_ANSI_APIS)
  569. ///Definition of the environment for this process.
  570. using ::boost::process::native_environment;
  571. #endif
  572. ///Definition of the environment for this process.
  573. using ::boost::process::wnative_environment;
  574. ///Get the process id of the current process.
  575. inline int get_id() { return ::boost::process::detail::api::get_id();}
  576. ///Get the native handle of the current process.
  577. inline native_handle_type native_handle() { return ::boost::process::detail::api::native_handle();}
  578. #if !defined(BOOST_NO_ANSI_APIS)
  579. ///Get the enviroment of the current process.
  580. inline native_environment environment() { return ::boost::process:: native_environment(); }
  581. #endif
  582. ///Get the enviroment of the current process.
  583. inline wnative_environment wenvironment() { return ::boost::process::wnative_environment(); }
  584. ///Get the path environment variable of the current process runs.
  585. inline std::vector<boost::filesystem::path> path()
  586. {
  587. #if defined(BOOST_WINDOWS_API)
  588. const ::boost::process::wnative_environment ne{};
  589. typedef typename ::boost::process::wnative_environment::const_entry_type value_type;
  590. static constexpr auto id = L"PATH";
  591. #else
  592. const ::boost::process::native_environment ne{};
  593. typedef typename ::boost::process::native_environment::const_entry_type value_type;
  594. static constexpr auto id = "PATH";
  595. #endif
  596. auto itr = std::find_if(ne.cbegin(), ne.cend(),
  597. [&](const value_type & e)
  598. {return id == ::boost::to_upper_copy(e.get_name(), ::boost::process::detail::process_locale());});
  599. if (itr == ne.cend())
  600. return {};
  601. auto vec = itr->to_vector();
  602. std::vector<boost::filesystem::path> val;
  603. val.resize(vec.size());
  604. std::copy(vec.begin(), vec.end(), val.begin());
  605. return val;
  606. }
  607. }
  608. }
  609. #endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENVIRONMENT_HPP_ */