From 1bdc3bed001168d8d2039955e57fead1ecc68144 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 9 Apr 2020 01:05:51 +0200 Subject: ipc: add --input-ipc-client option While --input-file was removed for justified reasons, wanting to pass down socket FDs this way is legitimate, useful, and easy to implement. One odd thing is that Fixes: #7592 --- DOCS/interface-changes.rst | 5 +++-- DOCS/man/options.rst | 29 +++++++++++++++++++++++++++++ input/ipc-unix.c | 24 ++++++++++++++++++++---- options/options.c | 3 +++ options/options.h | 1 + player/command.c | 2 +- 6 files changed, 57 insertions(+), 7 deletions(-) diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index cd391aa034..666af5f55e 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -59,7 +59,8 @@ Interface changes "error" field for end-file will silently break at some point in the future. - deprecate encoding mode (lack of maintainer) - - remove deprecated --input-file option + - remove deprecated --input-file option, add --input-ipc-client, which is + vaguely a replacement of the removed option, but not the same --- mpv 0.32.0 --- - change behavior when using legacy option syntax with options that start with two dashes (``--`` instead of a ``-``). Now, using the recommended @@ -81,7 +82,7 @@ Interface changes mpv 0.30.0 (related to the previous changelog entry). This affects video outputs like vo_x11 and vo_drm, and screenshots, but not much else. - deprecate --input-file (there are no plans to remove this short-term, - but it will probably eventually go away) + but it will probably eventually go away <- that was a lie) - deprecate --video-sync=display-adrop (might be removed if it's in the way; undeprecated or readded if it's not too much of a problem) - deprecate all input section commands (these will be changed/removed, as diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 7fd01f0592..f5b59d291a 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -3704,6 +3704,35 @@ Input See `JSON IPC`_ for details. +``--input-ipc-client=fd://`` + Connect a single IPC client to the given FD. This is somewhat similar to + ``--input-ipc-server``, except no socket is created, and instead the passed + FD is treated like a socket connection received from ``accept()``. In + practice, you could pass either a FD created by ``socketpair()``, or a pipe. + In both cases, you must sure the FD is actually inherited by mpv (do not + set the POSIX ``CLOEXEC`` flag). + + This is somewhat similar to the removed ``--input-file`` option, except it + supports only integer FDs, and cannot open actual paths. + + .. admonition:: Example + + ``--input-ipc-client=fd://123`` + + .. note:: + + Does not and will not work on Windows. + + .. warning:: + + Writing to the ``input-ipc-server`` option at runtime will start another + instance of an IPC client handler for the ``input-ipc-client`` option, + because initialization is bundled, and this thing is stupid. This is a + bug. Writing to ``input-ipc-client`` at runtime will start another IPC + client handler for the new value, without stopping the old one, even if + the FD value is the same (but the string is different e.g. due to + whitespace). This is not a bug. + ``--input-gamepad=`` Enable/disable SDL2 Gamepad support. Disabled by default. diff --git a/input/ipc-unix.c b/input/ipc-unix.c index e047c30145..ef9f26e5c0 100644 --- a/input/ipc-unix.c +++ b/input/ipc-unix.c @@ -18,7 +18,7 @@ #include #include #include - +#include #include #include #include @@ -248,9 +248,10 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd) { struct client_arg *client = talloc_ptrtype(NULL, client); *client = (struct client_arg){ - .client_name = talloc_asprintf(client, "ipc-%d", id), - .client_fd = fd, - .close_client_fd = true, + .client_name = + id >= 0 ? talloc_asprintf(client, "ipc-%d", id) : "ipc", + .client_fd = fd, + .close_client_fd = id >= 0, .writable = true, }; @@ -384,6 +385,21 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api, .death_pipe = {-1, -1}, }; + 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 { + ipc_start_client_json(arg, -1, fd); + } + } + talloc_free(opts); if (!arg->path || !arg->path[0]) diff --git a/options/options.c b/options/options.c index 170472af1c..c7d75b0648 100644 --- a/options/options.c +++ b/options/options.c @@ -719,6 +719,9 @@ static const m_option_t mp_opts[] = { {"input-terminal", OPT_FLAG(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)}, diff --git a/options/options.h b/options/options.h index 1eed3184b7..db48135b1a 100644 --- a/options/options.h +++ b/options/options.h @@ -319,6 +319,7 @@ typedef struct MPOpts { struct encode_opts *encode_opts; char *ipc_path; + char *ipc_client; int wingl_dwm_flush; diff --git a/player/command.c b/player/command.c index a41a636c7d..ff4d95ccd8 100644 --- a/player/command.c +++ b/player/command.c @@ -6229,7 +6229,7 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags, if (flags & UPDATE_INPUT) mp_input_update_opts(mpctx->input); - if (init || opt_ptr == &opts->ipc_path) { + if (init || opt_ptr == &opts->ipc_path || opt_ptr == &opts->ipc_client) { mp_uninit_ipc(mpctx->ipc_ctx); mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global); } -- cgit v1.2.3