environment.hpp 25 KB

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