env.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright (c) 2022 Klemens D. Morgenstern
  2. // Copyright (c) 2022 Samuel Venable
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_PROCESS_V2_ENV_HPP
  7. #define BOOST_PROCESS_V2_ENV_HPP
  8. #include <string>
  9. #include <vector>
  10. #include <boost/process/v2/detail/config.hpp>
  11. #include <boost/process/v2/detail/throw_error.hpp>
  12. #include <boost/process/v2/process_handle.hpp>
  13. #include <boost/process/v2/pid.hpp>
  14. #include <boost/process/v2/environment.hpp>
  15. BOOST_PROCESS_V2_BEGIN_NAMESPACE
  16. namespace detail
  17. {
  18. namespace ext
  19. {
  20. #if defined(BOOST_PROCESS_V2_WINDOWS)
  21. using native_env_handle_type = wchar_t *;
  22. using native_env_iterator = wchar_t *;
  23. #elif defined(__FreeBSD__)
  24. using native_env_handle_type = char **;
  25. using native_env_iterator = char **;
  26. #else
  27. using native_env_handle_type = char *;
  28. using native_env_iterator = char *;
  29. #endif
  30. struct native_env_handle_deleter
  31. {
  32. BOOST_PROCESS_V2_DECL void operator()(native_env_handle_type) const;
  33. };
  34. BOOST_PROCESS_V2_DECL native_env_iterator next(native_env_iterator nh);
  35. BOOST_PROCESS_V2_DECL native_env_iterator find_end(native_env_iterator nh);
  36. BOOST_PROCESS_V2_DECL const environment::char_type * dereference(native_env_iterator iterator);
  37. } // namespace ext
  38. } // namespace detail
  39. namespace ext {
  40. /// The view of an environment
  41. struct env_view
  42. {
  43. using native_handle_type = detail::ext::native_env_handle_type;
  44. using value_type = environment::key_value_pair_view;
  45. env_view() = default;
  46. env_view(env_view && nt) = default;
  47. native_handle_type native_handle() { return handle_.get(); }
  48. struct iterator
  49. {
  50. using value_type = environment::key_value_pair_view;
  51. using difference_type = int;
  52. using reference = environment::key_value_pair_view;
  53. using pointer = environment::key_value_pair_view;
  54. using iterator_category = std::forward_iterator_tag;
  55. iterator() = default;
  56. iterator(const iterator & ) = default;
  57. iterator(const detail::ext::native_env_iterator &native_handle) : iterator_(native_handle) {}
  58. iterator & operator++()
  59. {
  60. iterator_ = detail::ext::next(iterator_);
  61. return *this;
  62. }
  63. iterator operator++(int)
  64. {
  65. auto last = *this;
  66. iterator_ = detail::ext::next(iterator_);
  67. return last;
  68. }
  69. environment::key_value_pair_view operator*() const
  70. {
  71. return detail::ext::dereference(iterator_);
  72. }
  73. friend bool operator==(const iterator & l, const iterator & r) {return l.iterator_ == r.iterator_;}
  74. friend bool operator!=(const iterator & l, const iterator & r) {return l.iterator_ != r.iterator_;}
  75. private:
  76. detail::ext::native_env_iterator iterator_;
  77. };
  78. iterator begin() const {return iterator(handle_.get());}
  79. iterator end() const {return iterator(detail::ext::find_end(handle_.get()));}
  80. private:
  81. friend BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
  82. #if defined(BOOST_PROCESS_V2_WINDOWS)
  83. friend BOOST_PROCESS_V2_DECL env_view env(HANDLE handle, error_code & ec);
  84. #endif
  85. std::unique_ptr<typename remove_pointer<detail::ext::native_env_handle_type>::type,
  86. detail::ext::native_env_handle_deleter> handle_;
  87. };
  88. #if defined(BOOST_PROCESS_V2_WINDOWS)
  89. BOOST_PROCESS_V2_DECL env_view env(HANDLE handle, error_code & ec);
  90. BOOST_PROCESS_V2_DECL env_view env(HANDLE handle);
  91. #endif
  92. /// @{
  93. /// Get the environment of another process.
  94. BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
  95. BOOST_PROCESS_V2_DECL env_view env(pid_type pid);
  96. template<typename Executor>
  97. BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, error_code & ec)
  98. {
  99. #if defined(BOOST_PROCESS_V2_WINDOWS)
  100. return env(handle.native_handle(), ec);
  101. #else
  102. return env(handle.id(), ec);
  103. #endif
  104. }
  105. template<typename Executor>
  106. BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle)
  107. {
  108. #if defined(BOOST_PROCESS_V2_WINDOWS)
  109. return env(handle.native_handle());
  110. #else
  111. return env(handle.id());
  112. #endif
  113. }
  114. /// @}
  115. } // namespace ext
  116. BOOST_PROCESS_V2_END_NAMESPACE
  117. #endif // BOOST_PROCESS_V2_ENV_HPP