env.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #pragma once
  2. #include <reproc++/detail/array.hpp>
  3. #include <reproc++/detail/type_traits.hpp>
  4. namespace reproc {
  5. class env : public detail::array {
  6. public:
  7. enum type {
  8. extend,
  9. empty,
  10. };
  11. env(const char *const *envp = nullptr) // NOLINT
  12. : detail::array(envp, false)
  13. {}
  14. /*!
  15. `Env` must be iterable as a sequence of string pairs. Examples of
  16. types that satisfy this requirement are `std::vector<std::pair<std::string,
  17. std::string>>` and `std::map<std::string, std::string>`.
  18. The pairs in `env` represent the extra environment variables of the child
  19. process and are converted to the right format before being passed as the
  20. environment to `reproc_start` via the `env.extra` field of `reproc_options`.
  21. */
  22. template <typename Env,
  23. typename = detail::enable_if_not_char_array<Env>>
  24. env(const Env &env) // NOLINT
  25. : detail::array(from(env), true)
  26. {}
  27. private:
  28. template <typename Env>
  29. static const char *const *from(const Env &env);
  30. };
  31. template <typename Env>
  32. const char *const *env::from(const Env &env)
  33. {
  34. using name_size_type = typename Env::value_type::first_type::size_type;
  35. using value_size_type = typename Env::value_type::second_type::size_type;
  36. const char **envp = new const char *[env.size() + 1];
  37. std::size_t current = 0;
  38. for (const auto &entry : env) {
  39. const auto &name = entry.first;
  40. const auto &value = entry.second;
  41. // We add 2 to the size to reserve space for the '=' sign and the NUL
  42. // terminator at the end of the string.
  43. char *string = new char[name.size() + value.size() + 2];
  44. envp[current++] = string;
  45. for (name_size_type i = 0; i < name.size(); i++) {
  46. *string++ = name[i];
  47. }
  48. *string++ = '=';
  49. for (value_size_type i = 0; i < value.size(); i++) {
  50. *string++ = value[i];
  51. }
  52. *string = '\0';
  53. }
  54. envp[current] = nullptr;
  55. return envp;
  56. }
  57. }