[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/3] io/command: implement support for win32
From: |
marcandre . lureau |
Subject: |
[PATCH v2 2/3] io/command: implement support for win32 |
Date: |
Fri, 2 Sep 2022 15:18:59 +0400 |
From: Marc-André Lureau <marcandre.lureau@redhat.com>
This is a fairly straightforward implementation of the equivalent UNIX
version.
GLib uses _mkpipe() to setup the FDs. We take that for granted, and set
the underlying named-pipes to nonblocking. This is done by other
projects as well (found on github), but I am not confident this works
reliably (msdn SetNamedPipeHandleState documentation discourage this
usage).
Alternatively, we could setup the FDs ourself, and use UNIX sockets on
Windows, which can be used in blocking/non-blocking mode. I haven't
tried it, as I am not sure it is necessary.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
io/channel-command.c | 58 ++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 21 deletions(-)
diff --git a/io/channel-command.c b/io/channel-command.c
index 35ba14c6a2..9bc292f3fd 100644
--- a/io/channel-command.c
+++ b/io/channel-command.c
@@ -26,7 +26,6 @@
#include "qemu/sockets.h"
#include "trace.h"
-#ifndef WIN32
/**
* qio_channel_command_new_pid:
* @writefd: the FD connected to the command's stdin
@@ -60,7 +59,13 @@ qio_channel_command_new_pid(int writefd,
ioc->writefd = writefd;
ioc->pid = pid;
- trace_qio_channel_command_new_pid(ioc, writefd, readfd, pid);
+ trace_qio_channel_command_new_pid(ioc, writefd, readfd,
+#ifdef WIN32
+ GetProcessId(pid)
+#else
+ pid
+#endif
+ );
return ioc;
}
@@ -89,18 +94,6 @@ qio_channel_command_new_spawn(const char *const argv[],
return qio_channel_command_new_pid(stdinfd, stdoutfd, pid);
}
-#else /* WIN32 */
-QIOChannelCommand *
-qio_channel_command_new_spawn(const char *const argv[],
- int flags,
- Error **errp)
-{
- error_setg_errno(errp, ENOSYS,
- "Command spawn not supported on this platform");
- return NULL;
-}
-#endif /* WIN32 */
-
#ifndef WIN32
static int qio_channel_command_abort(QIOChannelCommand *ioc,
Error **errp)
@@ -143,6 +136,23 @@ static int qio_channel_command_abort(QIOChannelCommand
*ioc,
return 0;
}
+#else
+static int qio_channel_command_abort(QIOChannelCommand *ioc,
+ Error **errp)
+{
+ DWORD ret;
+
+ TerminateProcess(ioc->pid, 0);
+ ret = WaitForSingleObject(ioc->pid, 1000);
+ if (ret != WAIT_OBJECT_0) {
+ error_setg(errp,
+ "Process %llu refused to die",
+ (unsigned long long)GetProcessId(ioc->pid));
+ return -1;
+ }
+
+ return 0;
+}
#endif /* ! WIN32 */
@@ -166,9 +176,7 @@ static void qio_channel_command_finalize(Object *obj)
}
ioc->writefd = ioc->readfd = -1;
if (ioc->pid > 0) {
-#ifndef WIN32
qio_channel_command_abort(ioc, NULL);
-#endif
g_spawn_close_pid(ioc->pid);
}
}
@@ -233,14 +241,20 @@ static int qio_channel_command_set_blocking(QIOChannel
*ioc,
bool enabled,
Error **errp)
{
+ QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
+
#ifdef WIN32
- /* command spawn is not supported on win32 */
- g_assert_not_reached();
+ DWORD dwMode = PIPE_READMODE_BYTE | enabled ? PIPE_WAIT : PIPE_NOWAIT;
+
+ if ((cioc->writefd >= 0 &&
!SetNamedPipeHandleState((HANDLE)_get_osfhandle(cioc->writefd), &dwMode, NULL,
NULL)) ||
+ (cioc->readfd >= 0
&&!SetNamedPipeHandleState((HANDLE)_get_osfhandle(cioc->readfd), &dwMode, NULL,
NULL))) {
+ error_setg_win32(errp, GetLastError(), "Failed to set nonblocking");
+ return -1;
+ }
#else
- QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
- if (!g_unix_set_fd_nonblocking(cioc->writefd, !enabled, NULL) ||
- !g_unix_set_fd_nonblocking(cioc->readfd, !enabled, NULL)) {
+ if ((cioc->writefd >= 0 && !g_unix_set_fd_nonblocking(cioc->writefd,
!enabled, NULL)) ||
+ (cioc->readfd >= 0 && !g_unix_set_fd_nonblocking(cioc->readfd,
!enabled, NULL))) {
error_setg_errno(errp, errno, "Failed to set FD nonblocking");
return -1;
}
@@ -281,6 +295,8 @@ static int qio_channel_command_close(QIOChannel *ioc,
(unsigned long long)cioc->pid);
return -1;
}
+#else
+ WaitForSingleObject(cioc->pid, INFINITE);
#endif
if (rv < 0) {
--
2.37.2