Skip to content

Commit 970e5ba

Browse files
committed
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.
1 parent e5486b9 commit 970e5ba

2 files changed

Lines changed: 19 additions & 14 deletions

File tree

DOCS/man/options.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4551,14 +4551,16 @@ Input
45514551
.. admonition:: Example
45524552

45534553
``--input-ipc-client=fd://123``
4554+
``--input-ipc-client=handle://123``
45544555

45554556
.. note::
45564557

45574558
To use this option on Windows, the fd must refer to a wrapped
45584559
(created by ``_open_osfhandle``) named pipe server handle with a client
4559-
already connected. The named pipe must be created duplex with overlapped
4560-
IO and inheritable handles. The program communicates with mpv through
4561-
the client handle.
4560+
already connected. Alternatively, the Windows HANDLE can be passed by
4561+
prefixing it with handle:// if mpv inherited it from the parent. The
4562+
named pipe must be created duplex with overlapped IO and inheritable
4563+
handles. The program communicates with mpv through the client handle.
45624564

45634565
.. warning::
45644566

input/ipc-win.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <windows.h>
1919
#include <sddl.h>
20+
#include <stdint.h>
2021

2122
#include "osdep/io.h"
2223
#include "osdep/threads.h"
@@ -471,21 +472,23 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
471472
};
472473

473474
if (opts->ipc_client && opts->ipc_client[0]) {
474-
int fd = -1;
475+
HANDLE h = INVALID_HANDLE_VALUE;
476+
475477
bstr str = bstr0(opts->ipc_client);
476478
if (bstr_eatstart0(&str, "fd://") && str.len) {
477-
long long ll = bstrtoll(str, &str, 0);
478-
if (!str.len && ll >= 0 && ll <= INT_MAX)
479-
fd = ll;
479+
long long fd = bstrtoll(str, &str, 0);
480+
if (!str.len && fd >= 0 && fd <= INT_MAX)
481+
h = (HANDLE)_get_osfhandle(fd);
482+
} else if (bstr_eatstart0(&str, "handle://") && str.len) {
483+
long long handle = bstrtoll(str, &str, 0);
484+
if (!str.len && handle >= 0 && handle <= UINT32_MAX)
485+
h = (HANDLE)(uintptr_t)handle;
480486
}
481-
if (fd < 0) {
482-
MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
487+
488+
if (h && h != INVALID_HANDLE_VALUE && (intptr_t)h != -2) {
489+
ipc_start_client_json(arg, -1, h);
483490
} else {
484-
HANDLE h = (HANDLE)_get_osfhandle(fd);
485-
if (h && h != INVALID_HANDLE_VALUE && (intptr_t)h != -2)
486-
ipc_start_client_json(arg, -1, h);
487-
else
488-
MP_ERR(arg, "Invalid IPC client fd: '%d'\n", fd);
491+
MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
489492
}
490493
}
491494

0 commit comments

Comments
 (0)