[common] Add a way to set the process startup directory (#63)

This will be needed later for switching to sftp, since calling lcd in
sftp is tricky to get right (e.g. may or may not require /cygwin/c on
Windows, depending on whether sftp is native or not).
This commit is contained in:
Lutz Justen
2023-01-16 12:26:45 +01:00
committed by GitHub
parent 42f5ee9b44
commit f2177969fe
3 changed files with 24 additions and 2 deletions

View File

@@ -53,6 +53,10 @@ struct ProcessStartInfo {
// Command line, UTF-8 encoded. // Command line, UTF-8 encoded.
std::string command; std::string command;
// Full path to the process startup working directory.
// If empty, uses parent process working dir.
std::string startup_dir;
// If set, the process stdin is redirected to a pipe. // If set, the process stdin is redirected to a pipe.
// It not set, the input is connected to the stdin of the calling process. // It not set, the input is connected to the stdin of the calling process.
bool redirect_stdin = false; bool redirect_stdin = false;

View File

@@ -342,5 +342,20 @@ TEST_F(ProcessTest, TerminateAlreadyExited) {
EXPECT_OK(process->Terminate()); EXPECT_OK(process->Terminate());
} }
TEST_F(ProcessTest, StartupDir) {
ProcessStartInfo start_info;
start_info.command = "cmd /C cd";
start_info.startup_dir = "C:\\";
std::string std_out;
start_info.stdout_handler = [&std_out](const char* data, size_t) {
std_out += data;
return absl::OkStatus();
};
EXPECT_OK(process_factory_.Run(start_info));
EXPECT_EQ(std_out, "C:\\\r\n");
}
} // namespace } // namespace
} // namespace cdc_ft } // namespace cdc_ft

View File

@@ -719,6 +719,10 @@ absl::Status WinProcess::Start() {
Util::GetLastWin32Error()); Util::GetLastWin32Error());
} }
std::wstring startup_dir = Util::Utf8ToWideStr(start_info_.startup_dir);
const wchar_t* startup_dir_cstr =
!startup_dir.empty() ? startup_dir.c_str() : nullptr;
// Start the child process. // Start the child process.
success = CreateProcess(NULL, // No module name (use command line) success = CreateProcess(NULL, // No module name (use command line)
command_cstr, command_cstr,
@@ -727,8 +731,7 @@ absl::Status WinProcess::Start() {
TRUE, // Inherit handles TRUE, // Inherit handles
ToCreationFlags(start_info_.flags), ToCreationFlags(start_info_.flags),
NULL, // Use parent's environment block NULL, // Use parent's environment block
NULL, // Use parent's starting directory startup_dir_cstr, &si, &process_info_->pi);
&si, &process_info_->pi);
if (!success) { if (!success) {
return MakeStatus("CreateProcess() failed: %s", Util::GetLastWin32Error()); return MakeStatus("CreateProcess() failed: %s", Util::GetLastWin32Error());