input/ipc-win: allow Windows handles for --input-ipc-client
Previously, you could only provide a CRT FD, which works great for the most part, but when using CreateProcess on Windows, it requires the use of the reserved fields of STARTUPINFO to inherit the FD to a child mpv process. This becomes a problem for example if you use Go's os/exec API, which does not expose a way to set those reserved fields. Exposing a way to allow passing handles directly fixes the mentioned scenario, and makes --input-ipc-client more flexible at no cost.
This commit is contained in:
1 parent
6f6c29b0b4
commit
0fb136f685
2 files changed
+19
-14
No files matched your search
@@ -4555,14 +4555,16 @@ Input
|
||||
.. admonition:: Example
|
||||
|
||||
``--input-ipc-client=fd://123``
|
||||
``--input-ipc-client=handle://123``
|
||||
|
||||
.. note::
|
||||
|
||||
To use this option on Windows, the fd must refer to a wrapped
|
||||
(created by ``_open_osfhandle``) named pipe server handle with a client
|
||||
already connected. The named pipe must be created duplex with overlapped
|
||||
IO and inheritable handles. The program communicates with mpv through
|
||||
the client handle.
|
||||
already connected. Alternatively, the Windows HANDLE can be passed by
|
||||
prefixing it with handle:// if mpv inherited it from the parent. The
|
||||
named pipe must be created duplex with overlapped IO and inheritable
|
||||
handles. The program communicates with mpv through the client handle.
|
||||
|
||||
.. warning::
|
||||
|
||||
|
||||
+14
-11
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <sddl.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "osdep/io.h"
|
||||
#include "osdep/threads.h"
|
||||
@@ -471,21 +472,23 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
|
||||
};
|
||||
|
||||
if (opts->ipc_client && opts->ipc_client[0]) {
|
||||
int fd = -1;
|
||||
HANDLE h = INVALID_HANDLE_VALUE;
|
||||
|
||||
bstr str = bstr0(opts->ipc_client);
|
||||
if (bstr_eatstart0(&str, "fd://") && str.len) {
|
||||
long long ll = bstrtoll(str, &str, 0);
|
||||
if (!str.len && ll >= 0 && ll <= INT_MAX)
|
||||
fd = ll;
|
||||
long long fd = bstrtoll(str, &str, 0);
|
||||
if (!str.len && fd >= 0 && fd <= INT_MAX)
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
} else if (bstr_eatstart0(&str, "handle://") && str.len) {
|
||||
long long handle = bstrtoll(str, &str, 0);
|
||||
if (!str.len && handle >= 0 && handle <= UINT32_MAX)
|
||||
h = (HANDLE)(uintptr_t)handle;
|
||||
}
|
||||
if (fd < 0) {
|
||||
MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
|
||||
|
||||
if (h && h != INVALID_HANDLE_VALUE && (intptr_t)h != -2) {
|
||||
ipc_start_client_json(arg, -1, h);
|
||||
} else {
|
||||
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h && h != INVALID_HANDLE_VALUE && (intptr_t)h != -2)
|
||||
ipc_start_client_json(arg, -1, h);
|
||||
else
|
||||
MP_ERR(arg, "Invalid IPC client fd: '%d'\n", fd);
|
||||
MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user