@@ -283,7 +283,7 @@ SocketId StartSpawned(const ConnectInfo& connect_info)
283283 CloseHandle (pipe);
284284
285285 WSADATA dontcare;
286- KJ_WIN32 (WSAStartup (MAKEWORD (2 , 2 ), &dontcare) ! = 0 , " WSAStartup() failed" );
286+ KJ_WIN32 (WSAStartup (MAKEWORD (2 , 2 ), &dontcare) = = 0 , " WSAStartup() failed" );
287287
288288 SOCKET socket{WSASocketA (FROM_PROTOCOL_INFO , FROM_PROTOCOL_INFO , FROM_PROTOCOL_INFO , &info, 0 , WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT )};
289289 KJ_WINSOCK (socket, " WSASocket(FROM_PROTOCOL_INFO) failed" );
@@ -303,6 +303,28 @@ std::array<SocketId, 2> SocketPair()
303303 return {pair[0 ], pair[1 ]};
304304}
305305
306+ ProcessId StartProcess (const std::vector<std::string>& args)
307+ {
308+ #ifndef WIN32
309+ ProcessId pid = fork ();
310+ if (pid == -1 ) {
311+ throw std::system_error (errno, std::system_category (), " fork" );
312+ }
313+ if (!pid) {
314+ ExecProcess (args);
315+ }
316+ return pid;
317+ #else
318+ std::string cmd{CommandLineFromArgv (args)};
319+ STARTUPINFOA si{};
320+ si.cb = sizeof (si);
321+ PROCESS_INFORMATION pi{};
322+ KJ_WIN32 (CreateProcessA (nullptr , const_cast <char *>(cmd.c_str ()), nullptr , nullptr , FALSE , 0 , nullptr , nullptr , &si, &pi), " CreateProcess failed" );
323+ CloseHandle (pi.hThread );
324+ return reinterpret_cast <ProcessId>(pi.hProcess );
325+ #endif
326+ }
327+
306328void ExecProcess (const std::vector<std::string>& args)
307329{
308330 const std::vector<char *> argv{MakeArgv (args)};
@@ -326,7 +348,7 @@ int WaitProcess(ProcessId pid)
326348#else
327349 HANDLE handle{reinterpret_cast <HANDLE >(pid)};
328350 DWORD result{WaitForSingleObject (handle, INFINITE )};
329- KJ_WIN32 (result ! = WAIT_OBJECT_0 , " WaitForSingleObject(child) failed" );
351+ KJ_WIN32 (result = = WAIT_OBJECT_0 , " WaitForSingleObject(child) failed" );
330352 KJ_WIN32 (GetExitCodeProcess (handle, &result), " GetExitCodeProcess failed" );
331353 CloseHandle (handle);
332354 return result;
0 commit comments