2 #include <msp/core/systemerror.h>
3 #include <msp/io/handle_private.h>
4 #include <msp/strings/utils.h>
6 #include "process_private.h"
12 string quote_argument(const string &arg)
15 bool need_quotes = false;
16 bool backslash = false;
33 return "\""+result+"\"";
44 CloseHandle(priv->info.hProcess);
45 CloseHandle(priv->info.hThread);
48 void Process::platform_get_self_info(Private &priv)
50 priv.info.hProcess = GetCurrentProcess();
51 priv.info.hThread = 0;
52 priv.info.dwProcessId = GetCurrentProcessId();
53 priv.info.dwThreadId = 0;
56 void Process::execute(const string &command, bool path_search, const Arguments &args)
58 string cmdline = quote_argument(command);
59 for(const string &a: args)
60 append(cmdline, " ", quote_argument(a));
63 startup.cb = sizeof(STARTUPINFO);
64 startup.lpReserved = 0;
65 startup.lpDesktop = 0;
68 startup.cbReserved2 = 0;
69 startup.lpReserved2 = 0;
72 startup.dwFlags |= STARTF_USESTDHANDLES;
73 HANDLE self_handle = self().priv->info.hProcess;
74 HANDLE cin_handle = (cin ? *cin->get_handle(IO::M_READ) : GetStdHandle(STD_INPUT_HANDLE));
75 DuplicateHandle(self_handle, cin_handle, self_handle, &startup.hStdInput, 0, true, DUPLICATE_SAME_ACCESS);
76 HANDLE cout_handle = (cout ? *cout->get_handle(IO::M_WRITE) : GetStdHandle(STD_OUTPUT_HANDLE));
77 DuplicateHandle(self_handle, cout_handle, self_handle, &startup.hStdOutput, 0, true, DUPLICATE_SAME_ACCESS);
78 HANDLE cerr_handle = (cerr ? *cerr->get_handle(IO::M_WRITE) : GetStdHandle(STD_ERROR_HANDLE));
79 DuplicateHandle(self_handle, cerr_handle, self_handle, &startup.hStdError, 0, true, DUPLICATE_SAME_ACCESS);
81 const char *cmdptr = (path_search ? 0 : command.c_str());
82 const char *wd = (work_dir.empty() ? 0 : work_dir.c_str());
83 if(!CreateProcess(cmdptr, const_cast<char *>(cmdline.c_str()), 0, 0, true, 0, 0, wd, &startup, &priv->info))
84 throw system_error("CreateProcess");
88 CloseHandle(startup.hStdInput);
89 CloseHandle(startup.hStdOutput);
90 CloseHandle(startup.hStdError);
96 TerminateProcess(priv->info.hProcess, 0);
99 bool Process::wait(bool block)
102 throw logic_error("not running");
104 DWORD ret = WaitForSingleObject(priv->info.hProcess, (block ? INFINITE : 0));
106 throw system_error("WaitForSingleObject");
108 if(ret==WAIT_OBJECT_0)
113 if(GetExitCodeProcess(priv->info.hProcess, &ec))
120 void Process::terminate()
122 TerminateProcess(priv->info.hProcess, 1);
127 TerminateProcess(priv->info.hProcess, 1);
130 void Process::interrupt()
132 TerminateProcess(priv->info.hProcess, 1);
136 Process::Private::Private()
140 info.dwProcessId = 0;