67 fdt result_fd = INVALID_HANDLE_VALUE;
70 SECURITY_ATTRIBUTES SecurityAttributes;
71 ZeroMemory(&SecurityAttributes,
sizeof SecurityAttributes);
72 SecurityAttributes.bInheritHandle =
true;
79 result_fd = GetStdHandle(STD_INPUT_HANDLE);
81 result_fd = CreateFileW(
87 FILE_ATTRIBUTE_READONLY,
94 result_fd = GetStdHandle(STD_OUTPUT_HANDLE);
96 result_fd = CreateFileW(
102 FILE_ATTRIBUTE_NORMAL,
109 result_fd = GetStdHandle(STD_ERROR_HANDLE);
111 result_fd = CreateFileW(
117 FILE_ATTRIBUTE_NORMAL,
125 if(result_fd == INVALID_HANDLE_VALUE)
126 perror((
"Failed to open " + name +
" file " +
file).c_str());
133 int flags = 0, mode = 0;
145 flags = O_CREAT | O_WRONLY;
146 mode = S_IRUSR | S_IWUSR;
147 name = fd == STDOUT_FILENO ?
"stdout" :
"stderr";
154 const fdt result_fd = open(
file.c_str(), flags, mode);
157 perror((
"Failed to open " + name +
" file " +
file).c_str());
254 const std::string &what,
255 const std::vector<std::string> &argv,
256 const std::string &std_input,
257 const std::string &std_output,
258 const std::string &std_error)
262 std::wstring cmdline;
265 cmdline = quote_windows_arg(
widen(what));
267 for(std::size_t i = 1; i < argv.size(); i++)
270 cmdline += quote_windows_arg(
widen(argv[i]));
273 PROCESS_INFORMATION piProcInfo;
274 STARTUPINFOW siStartInfo;
276 ZeroMemory(&piProcInfo,
sizeof piProcInfo);
277 ZeroMemory(&siStartInfo,
sizeof siStartInfo);
279 siStartInfo.cb =
sizeof siStartInfo;
285 siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
288 std::vector<wchar_t> mutable_cmdline(cmdline.begin(), cmdline.end());
289 mutable_cmdline.push_back(0);
290 wchar_t *cmdline_ptr = mutable_cmdline.data();
292 BOOL bSuccess = CreateProcessW(
307 std::string windows_error = get_last_error_as_string();
309 if(!std_input.empty())
310 CloseHandle(siStartInfo.hStdInput);
311 if(!std_output.empty())
312 CloseHandle(siStartInfo.hStdOutput);
313 if(!std_error.empty())
314 CloseHandle(siStartInfo.hStdError);
317 std::ofstream stderr_stream(std_error);
318 stderr_stream << windows_error;
324 WaitForSingleObject(piProcInfo.hProcess, INFINITE);
326 if(!std_input.empty())
327 CloseHandle(siStartInfo.hStdInput);
328 if(!std_output.empty())
329 CloseHandle(siStartInfo.hStdOutput);
330 if(!std_error.empty())
331 CloseHandle(siStartInfo.hStdError);
336 if(!GetExitCodeProcess(piProcInfo.hProcess, &exit_code))
338 CloseHandle(piProcInfo.hProcess);
339 CloseHandle(piProcInfo.hThread);
343 CloseHandle(piProcInfo.hProcess);
344 CloseHandle(piProcInfo.hThread);
353 if(stdin_fd == -1 || stdout_fd == -1 || stderr_fd == -1)
357 sigset_t new_mask, old_mask;
358 sigemptyset(&new_mask);
359 sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
362 pid_t childpid = fork();
370 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
372 std::vector<char *> _argv(argv.size()+1);
373 for(std::size_t i=0; i<argv.size(); i++)
374 _argv[i]=strdup(argv[i].c_str());
376 _argv[argv.size()]=
nullptr;
378 if(stdin_fd!=STDIN_FILENO)
379 dup2(stdin_fd, STDIN_FILENO);
380 if(stdout_fd!=STDOUT_FILENO)
381 dup2(stdout_fd, STDOUT_FILENO);
382 if(stderr_fd != STDERR_FILENO)
383 dup2(stderr_fd, STDERR_FILENO);
386 execvp(what.c_str(), _argv.data());
389 perror(std::string(
"execvp "+what+
" failed").c_str());
398 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
403 while(waitpid(childpid, &status, 0)==-1)
411 perror(
"Waiting for child process failed");
412 if(stdin_fd!=STDIN_FILENO)
414 if(stdout_fd!=STDOUT_FILENO)
416 if(stderr_fd != STDERR_FILENO)
424 if(stdin_fd!=STDIN_FILENO)
426 if(stdout_fd!=STDOUT_FILENO)
428 if(stderr_fd != STDERR_FILENO)
431 return WEXITSTATUS(status);
437 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
439 if(stdin_fd!=STDIN_FILENO)
441 if(stdout_fd!=STDOUT_FILENO)
443 if(stderr_fd != STDERR_FILENO)
526 const std::string &what,
527 const std::vector<std::string> &argv,
528 const std::string &std_input,
529 std::ostream &std_output,
530 const std::string &std_error)
535 int result =
run(what, argv, std_input, tmpi(), std_error);
537 std::ifstream instream(tmpi());
540 std_output << instream.rdbuf();
545 if(pipe(pipefd) == -1)
549 int stdout_fd = pipefd[1];
552 if(stdin_fd == -1 || stdout_fd == -1 || stderr_fd == -1)
556 sigset_t new_mask, old_mask;
557 sigemptyset(&new_mask);
558 sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
561 pid_t childpid = fork();
569 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
573 std::vector<char *> _argv(argv.size() + 1);
574 for(std::size_t i = 0; i < argv.size(); i++)
575 _argv[i] = strdup(argv[i].c_str());
577 _argv[argv.size()] =
nullptr;
579 if(stdin_fd != STDIN_FILENO)
580 dup2(stdin_fd, STDIN_FILENO);
581 if(stdout_fd != STDOUT_FILENO)
582 dup2(stdout_fd, STDOUT_FILENO);
583 if(stderr_fd != STDERR_FILENO)
584 dup2(stderr_fd, STDERR_FILENO);
587 execvp(what.c_str(), _argv.data());
590 perror(std::string(
"execvp " + what +
" failed").c_str());
599 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
607 while((bytes_read = read(pipefd[0], buffer.data(),
buffer_size)) > 0)
608 std_output.write(buffer.data(), bytes_read);
613 while(waitpid(childpid, &status, 0) == -1)
621 perror(
"Waiting for child process failed");
622 if(stdin_fd != STDIN_FILENO)
624 if(stdout_fd != STDOUT_FILENO)
626 if(stderr_fd != STDERR_FILENO)
634 if(stdin_fd != STDIN_FILENO)
636 if(stdout_fd != STDOUT_FILENO)
638 if(stderr_fd != STDERR_FILENO)
641 return WEXITSTATUS(status);
647 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
649 if(stdin_fd != STDIN_FILENO)
651 if(stdout_fd != STDOUT_FILENO)
653 if(stderr_fd != STDERR_FILENO)