Skip to content

Commit 4d3a8ac

Browse files
committed
Support cwd on Windows
This requires making cwd arg be either narrow or wide char depending on platform and plumbing the argument to CreateProcessW. Since `env_char_t` and `env_str_t` is now being used beyond just env, I've renamed those types to `platform_char_t` and `platform_str_t`. `env_char_t` and `env_str_t` are provided as alias to the new name for backwards compatibility.
1 parent 3afe581 commit 4d3a8ac

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

subprocess.hpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,16 @@ class OSError: public std::runtime_error
156156

157157
//Environment Variable types
158158
#ifndef _MSC_VER
159-
using env_string_t = std::string;
160-
using env_char_t = char;
159+
using platform_str_t = std::string;
160+
using platform_char_t = char;
161161
#else
162-
using env_string_t = std::wstring;
163-
using env_char_t = wchar_t;
162+
using platform_str_t = std::wstring;
163+
using platform_char_t = wchar_t;
164164
#endif
165-
using env_map_t = std::map<env_string_t, env_string_t>;
166-
using env_vector_t = std::vector<env_char_t>;
165+
using env_str_t = platform_str_t;
166+
using env_char_t = platform_char_t;
167+
using env_map_t = std::map<platform_str_t, platform_str_t>;
168+
using env_vector_t = std::vector<platform_char_t>;
167169

168170
//--------------------------------------------------------------------
169171
namespace util
@@ -333,14 +335,14 @@ namespace util
333335
while (*variable_strings_ptr)
334336
{
335337
// Create a string from Variable String
336-
env_string_t current_line(variable_strings_ptr);
338+
platform_str_t current_line(variable_strings_ptr);
337339
// Find the first "equals" sign.
338340
auto pos = current_line.find(delimeter);
339341
// Assuming it's not missing ...
340342
if(pos!=std::wstring::npos){
341343
// ... parse the key and value.
342-
env_string_t key = current_line.substr(0, pos);
343-
env_string_t value = current_line.substr(pos + del_len);
344+
platform_str_t key = current_line.substr(0, pos);
345+
platform_str_t value = current_line.substr(pos + del_len);
344346
// Map the entry.
345347
mapped_environment[key] = value;
346348
}
@@ -368,7 +370,7 @@ namespace util
368370
// And fill'er up.
369371
for(auto kv: source_map){
370372
// Create the line
371-
env_string_t current_line(kv.first); current_line += L"="; current_line += kv.second;
373+
platform_str_t current_line(kv.first); current_line += L"="; current_line += kv.second;
372374
// Add the line to the buffer.
373375
std::copy(current_line.begin(), current_line.end(), std::back_inserter(environment_map_buffer));
374376
// Append a null
@@ -730,10 +732,11 @@ struct executable: string_arg
730732
*
731733
* Eg: cwd{"/som/path/x"}
732734
*/
733-
struct cwd: string_arg
735+
struct cwd
734736
{
735-
template <typename T>
736-
cwd(T&& arg): string_arg(std::forward<T>(arg)) {}
737+
explicit cwd(const platform_str_t &cwd): cwd_(cwd) {}
738+
explicit cwd(platform_str_t &&cwd): cwd_(std::move(cwd)) {}
739+
platform_str_t cwd_;
737740
};
738741

739742
/*!
@@ -1352,7 +1355,7 @@ class Popen
13521355
bool session_leader_ = false;
13531356

13541357
std::string exe_name_;
1355-
std::string cwd_;
1358+
platform_str_t cwd_;
13561359
env_map_t env_;
13571360
preexec_func preexec_fn_;
13581361

@@ -1540,6 +1543,8 @@ inline void Popen::execute_process() noexcept(false)
15401543

15411544
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
15421545

1546+
const wchar_t *cwd_arg = this->cwd_.empty() ? NULL : cwd_.c_str();
1547+
15431548
// Create the child process.
15441549
bSuccess = CreateProcessW(NULL,
15451550
szCmdline, // command line
@@ -1548,7 +1553,7 @@ inline void Popen::execute_process() noexcept(false)
15481553
TRUE, // handles are inherited
15491554
creation_flags, // creation flags
15501555
environment_string_table_ptr, // use provided environment
1551-
NULL, // use parent's current directory
1556+
cwd_arg, // use provided current directory
15521557
&siStartInfo, // STARTUPINFOW pointer
15531558
&piProcInfo); // receives PROCESS_INFORMATION
15541559

@@ -1663,7 +1668,7 @@ namespace detail {
16631668
}
16641669

16651670
inline void ArgumentDeducer::set_option(cwd&& cwdir) {
1666-
popen_->cwd_ = std::move(cwdir.arg_value);
1671+
popen_->cwd_ = std::move(cwdir.cwd_);
16671672
}
16681673

16691674
inline void ArgumentDeducer::set_option(bufsize&& bsiz) {

0 commit comments

Comments
 (0)