1 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
2 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
3 // Copyright (c) 2009 Boris Schaeling
4 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
5 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
6 // Copyright (c) 2016 Hartmut Kaiser
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef HPX_PROCESS_WINDOWS_INITIALIZERS_SET_ENV_HPP
12 #define HPX_PROCESS_WINDOWS_INITIALIZERS_SET_ENV_HPP
13
14 #include <hpx/config.hpp>
15
16 #if defined(HPX_WINDOWS)
17 #include <hpx/components/process/util/windows/initializers/initializer_base.hpp>
18 #include <hpx/runtime/serialization/string.hpp>
19
20 #include <boost/range/numeric.hpp>
21
22 #include <cstddef>
23 #include <cstring>
24 #include <iterator>
25 #include <numeric>
26 #include <vector>
27 #include <windows.h>
28
29 namespace hpx { namespace components { namespace process { namespace windows {
30
31 namespace initializers {
32
33 template <class Range, bool Unicode>
34 class set_env_ : public initializer_base
35 {
36 private:
37 typedef typename Range::value_type String;
38 typedef typename String::value_type Char;
39
get_size(std::size_t len,String const & s)40 static std::size_t get_size(std::size_t len, String const& s)
41 {
42 return len + s.size() + 1;
43 }
44
45 struct copy_env
46 {
copy_envhpx::components::process::windows::initializers::set_env_::copy_env47 copy_env(Char* curr)
48 : curr_(curr)
49 {}
50
operator ()hpx::components::process::windows::initializers::set_env_::copy_env51 void operator()(String const& s)
52 {
53 std::memcpy(curr_, s.c_str(), s.size());
54 curr_ += s.size();
55 *curr_++ = 0;
56 }
57
58 Char* curr_;
59 };
60
61 public:
set_env_()62 set_env_()
63 {
64 env_.resize(1);
65 env_[0] = 0;
66 }
67
set_env_(const Range & envs)68 set_env_(const Range &envs)
69 {
70 std::size_t s = std::accumulate(envs.begin(), envs.end(),
71 std::size_t(0), &set_env_::get_size);
72
73 env_.resize(s + 1);
74 std::for_each(envs.begin(), envs.end(), copy_env(env_.data()));
75 env_[env_.size() - 1] = 0;
76 }
77
78 template <class WindowsExecutor>
on_CreateProcess_setup(WindowsExecutor & e) const79 void on_CreateProcess_setup(WindowsExecutor &e) const
80 {
81 e.env = LPVOID(env_.data());
82 if (Unicode)
83 e.creation_flags |= CREATE_UNICODE_ENVIRONMENT;
84 }
85
86 private:
87 friend class hpx::serialization::access;
88
89 template <typename Archive>
serialize(Archive & ar,unsigned const)90 void serialize(Archive& ar, unsigned const)
91 {
92 ar & env_;
93 }
94
95 std::vector<Char> env_;
96 };
97
98 #if defined(_UNICODE) || defined(UNICODE)
99 template <class Range>
set_env(const Range & envs)100 set_env_<Range, true> set_env(const Range &envs)
101 {
102 return set_env_<Range, true>(envs);
103 }
104 #else
105 template <class Range>
set_env(const Range & envs)106 set_env_<Range, false> set_env(const Range &envs)
107 {
108 return set_env_<Range, false>(envs);
109 }
110 #endif
111
112 }
113
114 }}}}
115
116 #endif
117 #endif
118