Skip to content

Commit 8f4bbfe

Browse files
committed
util, gen: Fix Windows process launching support
1 parent a1748e2 commit 8f4bbfe

4 files changed

Lines changed: 32 additions & 10 deletions

File tree

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ target_include_directories(mputil PRIVATE
144144
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
145145
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>)
146146
target_link_libraries(mputil PUBLIC CapnProto::kj)
147+
if(WIN32)
148+
target_link_libraries(mputil PUBLIC ws2_32)
149+
endif()
147150

148151
# libmultiprocess.a runtime library
149152
set(MP_PUBLIC_HEADERS

include/mp/util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ SocketId StartSpawned(const ConnectInfo& connect_info);
291291
//! between parent and child processes.
292292
std::array<SocketId, 2> SocketPair();
293293

294+
//! Start a child process and return a handle that can be passed to
295+
//! WaitProcess().
296+
ProcessId StartProcess(const std::vector<std::string>& args);
297+
294298
//! Call execvp with vector args.
295299
//! Not safe to call in a post-fork child of a multi-threaded process.
296300
//! Currently only used by mpgen at build time.

src/mp/gen.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <stdexcept>
2828
#include <string>
2929
#include <system_error>
30-
#include <unistd.h>
3130
#include <utility>
3231
#include <vector>
3332

@@ -180,13 +179,7 @@ static void Generate(kj::StringPtr src_prefix,
180179
}
181180
args.emplace_back("--output=" capnp_PREFIX "/bin/capnpc-c++");
182181
args.emplace_back(src_file);
183-
const int pid = fork();
184-
if (pid == -1) {
185-
throw std::system_error(errno, std::system_category(), "fork");
186-
}
187-
if (!pid) {
188-
mp::ExecProcess(args);
189-
}
182+
const mp::ProcessId pid = mp::StartProcess(args);
190183
const int status = mp::WaitProcess(pid);
191184
if (status) {
192185
throw std::runtime_error("Invoking " capnp_PREFIX "/bin/capnp failed");

src/mp/util.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
306328
void 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

Comments
 (0)