input/ipc-win: support fd:// for --input-ipc-client

This makes --input-ipc-client work on Windows.

To use this feature, a parent process needs to create a connected named pipe,
wrap the server handle in a CRT fd, and then spawn mpv as a child process
with the fd as the --input-ipc-client parameter.
The process can then communicate through the client handle.

The named pipe must be created duplex with overlapped IO and inheritable
handles.
This commit is contained in:
nanahi 2024-07-28 07:09:43 -04:00 committed by Kacper Michajłow
parent 87686a80e5
commit bb0932a3ad
3 changed files with 24 additions and 3 deletions

View File

@ -4243,7 +4243,11 @@ Input
.. note::
Does not and will not work on Windows.
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.
.. warning::

View File

@ -464,6 +464,25 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
.client_api = client_api,
};
if (opts->ipc_client && opts->ipc_client[0]) {
int fd = -1;
if (strncmp(opts->ipc_client, "fd://", 5) == 0) {
char *end;
unsigned long l = strtoul(opts->ipc_client + 5, &end, 0);
if (!end[0] && l <= INT_MAX)
fd = l;
}
if (fd < 0) {
MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
} 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);
}
}
if (!opts->ipc_path || !*opts->ipc_path)
goto out;

View File

@ -881,9 +881,7 @@ static const m_option_t mp_opts[] = {
{"input-terminal", OPT_BOOL(consolecontrols), .flags = UPDATE_TERM},
{"input-ipc-server", OPT_STRING(ipc_path), .flags = M_OPT_FILE},
#if HAVE_POSIX
{"input-ipc-client", OPT_STRING(ipc_client)},
#endif
{"screenshot", OPT_SUBSTRUCT(screenshot_image_opts, screenshot_conf)},
{"screenshot-template", OPT_STRING(screenshot_template)},