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
|
.. admonition:: Example
|
||||||
|
|
||||||
``--input-ipc-client=fd://123``
|
``--input-ipc-client=fd://123``
|
||||||
|
``--input-ipc-client=handle://123``
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
To use this option on Windows, the fd must refer to a wrapped
|
To use this option on Windows, the fd must refer to a wrapped
|
||||||
(created by ``_open_osfhandle``) named pipe server handle with a client
|
(created by ``_open_osfhandle``) named pipe server handle with a client
|
||||||
already connected. The named pipe must be created duplex with overlapped
|
already connected. Alternatively, the Windows HANDLE can be passed by
|
||||||
IO and inheritable handles. The program communicates with mpv through
|
prefixing it with handle:// if mpv inherited it from the parent. The
|
||||||
the client handle.
|
named pipe must be created duplex with overlapped IO and inheritable
|
||||||
|
handles. The program communicates with mpv through the client handle.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
|||||||
+14
-11
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "osdep/io.h"
|
#include "osdep/io.h"
|
||||||
#include "osdep/threads.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]) {
|
if (opts->ipc_client && opts->ipc_client[0]) {
|
||||||
int fd = -1;
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
bstr str = bstr0(opts->ipc_client);
|
bstr str = bstr0(opts->ipc_client);
|
||||||
if (bstr_eatstart0(&str, "fd://") && str.len) {
|
if (bstr_eatstart0(&str, "fd://") && str.len) {
|
||||||
long long ll = bstrtoll(str, &str, 0);
|
long long fd = bstrtoll(str, &str, 0);
|
||||||
if (!str.len && ll >= 0 && ll <= INT_MAX)
|
if (!str.len && fd >= 0 && fd <= INT_MAX)
|
||||||
fd = ll;
|
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 {
|
} else {
|
||||||
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
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
|
|
||||||
MP_ERR(arg, "Invalid IPC client fd: '%d'\n", fd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user