env.hpp 4.1 KB

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