ian@0
|
1 //
|
ian@0
|
2 // Boost.Process
|
ian@0
|
3 // ~~~~~~~~~~~~~
|
ian@0
|
4 //
|
ian@0
|
5 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
ian@0
|
6 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
ian@0
|
7 // Copyright (c) 2009 Boris Schaeling
|
ian@0
|
8 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
ian@0
|
9 //
|
ian@0
|
10 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
ian@0
|
11 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
ian@0
|
12 //
|
ian@0
|
13
|
ian@0
|
14 /**
|
ian@0
|
15 * \file boost/process/detail/windows_helpers.hpp
|
ian@0
|
16 *
|
ian@0
|
17 * Includes the declaration of helper functions for Windows systems.
|
ian@0
|
18 */
|
ian@0
|
19
|
ian@0
|
20 #ifndef BOOST_PROCESS_WINDOWS_HELPERS_HPP
|
ian@0
|
21 #define BOOST_PROCESS_WINDOWS_HELPERS_HPP
|
ian@0
|
22
|
ian@0
|
23 #include <boost/process/config.hpp>
|
ian@0
|
24 #include <boost/process/environment.hpp>
|
ian@0
|
25 #include <boost/shared_array.hpp>
|
ian@0
|
26 #include <string>
|
ian@0
|
27 #include <vector>
|
ian@0
|
28 #include <cstddef>
|
ian@0
|
29 #include <string.h>
|
ian@0
|
30 #include <windows.h>
|
ian@0
|
31
|
ian@0
|
32 namespace boost {
|
ian@0
|
33 namespace process {
|
ian@0
|
34 namespace detail {
|
ian@0
|
35
|
ian@0
|
36 /**
|
ian@0
|
37 * Converts an environment to a string used by CreateProcess().
|
ian@0
|
38 *
|
ian@0
|
39 * Converts the environment's contents to the format used by the
|
ian@0
|
40 * CreateProcess() system call. The returned char* string is
|
ian@0
|
41 * allocated in dynamic memory; the caller must free it when not
|
ian@0
|
42 * used any more. This is enforced by the use of a shared pointer.
|
ian@0
|
43 *
|
ian@0
|
44 * This operation is only available on Windows systems.
|
ian@0
|
45 *
|
ian@0
|
46 * \return A dynamically allocated char* string that represents
|
ian@0
|
47 * the environment's content. This string is of the form
|
ian@0
|
48 * var1=value1\\0var2=value2\\0\\0.
|
ian@0
|
49 */
|
ian@0
|
50 inline boost::shared_array<char> environment_to_windows_strings(environment
|
ian@0
|
51 &env)
|
ian@0
|
52 {
|
ian@0
|
53 boost::shared_array<char> envp;
|
ian@0
|
54
|
ian@0
|
55 if (env.empty())
|
ian@0
|
56 {
|
ian@0
|
57 envp.reset(new char[2]);
|
ian@0
|
58 ZeroMemory(envp.get(), 2);
|
ian@0
|
59 }
|
ian@0
|
60 else
|
ian@0
|
61 {
|
ian@0
|
62 std::string s;
|
ian@0
|
63 for (environment::const_iterator it = env.begin(); it != env.end();
|
ian@0
|
64 ++it)
|
ian@0
|
65 {
|
ian@0
|
66 s += it->first + "=" + it->second;
|
ian@0
|
67 s.push_back(0);
|
ian@0
|
68 }
|
ian@0
|
69 envp.reset(new char[s.size() + 1]);
|
ian@0
|
70 #if (BOOST_MSVC >= 1400)
|
ian@0
|
71 memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1);
|
ian@0
|
72 #else
|
ian@0
|
73 memcpy(envp.get(), s.c_str(), s.size() + 1);
|
ian@0
|
74 #endif
|
ian@0
|
75 }
|
ian@0
|
76
|
ian@0
|
77 return envp;
|
ian@0
|
78 }
|
ian@0
|
79
|
ian@0
|
80 /**
|
ian@0
|
81 * Converts the command line to a plain string.
|
ian@0
|
82 *
|
ian@0
|
83 * Converts the command line's list of arguments to the format expected by the
|
ian@0
|
84 * \a lpCommandLine parameter in the CreateProcess() system call.
|
ian@0
|
85 *
|
ian@0
|
86 * This operation is only available on Windows systems.
|
ian@0
|
87 *
|
ian@0
|
88 * \return A dynamically allocated string holding the command line
|
ian@0
|
89 * to be passed to the executable. It is returned in a
|
ian@0
|
90 * shared_array object to ensure its release at some point.
|
ian@0
|
91 */
|
ian@0
|
92 template <class Arguments>
|
ian@0
|
93 inline boost::shared_array<char> collection_to_windows_cmdline(const Arguments
|
ian@0
|
94 &args)
|
ian@0
|
95 {
|
ian@0
|
96 typedef std::vector<std::string> arguments_t;
|
ian@0
|
97 arguments_t args2;
|
ian@0
|
98 typename Arguments::size_type i = 0;
|
ian@0
|
99 std::size_t size = 0;
|
ian@0
|
100 for (typename Arguments::const_iterator it = args.begin(); it != args.end();
|
ian@0
|
101 ++it)
|
ian@0
|
102 {
|
ian@0
|
103 std::string arg = *it;
|
ian@0
|
104
|
ian@0
|
105 std::string::size_type pos = 0;
|
ian@0
|
106 while ( (pos = arg.find('"', pos)) != std::string::npos)
|
ian@0
|
107 {
|
ian@0
|
108 arg.replace(pos, 1, "\\\"");
|
ian@0
|
109 pos += 2;
|
ian@0
|
110 }
|
ian@0
|
111
|
ian@0
|
112 if (arg.find(' ') != std::string::npos)
|
ian@0
|
113 arg = '\"' + arg + '\"';
|
ian@0
|
114
|
ian@0
|
115 if (i++ != args.size() - 1)
|
ian@0
|
116 arg += ' ';
|
ian@0
|
117
|
ian@0
|
118 args2.push_back(arg);
|
ian@0
|
119 size += arg.size() + 1;
|
ian@0
|
120 }
|
ian@0
|
121
|
ian@0
|
122 boost::shared_array<char> cmdline(new char[size]);
|
ian@0
|
123 cmdline.get()[0] = '\0';
|
ian@0
|
124 for (arguments_t::size_type i = 0; i < args.size(); ++i)
|
ian@0
|
125 #if (BOOST_MSVC >= 1400)
|
ian@0
|
126 strcat_s(cmdline.get(), size, args2[i].c_str());
|
ian@0
|
127 #else
|
ian@0
|
128 strncat(cmdline.get(), args2[i].c_str(), args2[i].size());
|
ian@0
|
129 #endif
|
ian@0
|
130
|
ian@0
|
131 return cmdline;
|
ian@0
|
132 }
|
ian@0
|
133
|
ian@0
|
134 }
|
ian@0
|
135 }
|
ian@0
|
136 }
|
ian@0
|
137
|
ian@0
|
138 #endif
|