From e27c523a10708b7265c33a4bae631663df4bb297 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 16 Aug 2020 02:54:44 +0200 Subject: command: extend subprocess command stdin, change behavior Make it possible to feed a string to stdin of a subprocess. Out of laziness, it can't be an arbitrary byte string. (Would require adding an option type that takes in a Lua byte string.) Do not set stdin of a subprocess to fd 0 (i.e. mpv's stdin) anymore, because it makes things more consistent. Enabling stdin didn't make too much sense in the first place, so this behavior change seems justifiable. win32 support missing. Fixes: #8003 --- player/command.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'player/command.c') diff --git a/player/command.c b/player/command.c index 560b9d71e2..5b9e8bcbb4 100644 --- a/player/command.c +++ b/player/command.c @@ -5343,6 +5343,11 @@ static void subprocess_read(void *p, char *data, size_t size) } } +static void subprocess_write(void *p) +{ + // Unused; we write a full buffer. +} + static void cmd_subprocess(void *p) { struct mp_cmd_ctx *cmd = p; @@ -5351,6 +5356,8 @@ static void cmd_subprocess(void *p) bool playback_only = cmd->args[1].v.i; bool detach = cmd->args[5].v.i; char **env = cmd->args[6].v.str_list; + bstr stdin_data = bstr0(cmd->args[7].v.s); + bool passthrough_stdin = cmd->args[8].v.i; if (env && !env[0]) env = NULL; // do not actually set an empty environment @@ -5361,6 +5368,12 @@ static void cmd_subprocess(void *p) return; } + if (stdin_data.len && passthrough_stdin) { + MP_ERR(mpctx, "both stdin_data and passthrough_stdin set\n"); + cmd->success = false; + return; + } + void *tmp = talloc_new(NULL); struct mp_log *fdlog = mp_log_new(tmp, mpctx->log, cmd->cmd->sender); @@ -5392,7 +5405,7 @@ static void cmd_subprocess(void *p) .fds = { { .fd = 0, // stdin - .src_fd = 0, + .src_fd = passthrough_stdin ? 0 : -1, }, }, .num_fds = 1, @@ -5408,6 +5421,16 @@ static void cmd_subprocess(void *p) .on_read_ctx = &fdctx[fd], }; } + // stdin + if (stdin_data.len) { + opts.fds[0] = (struct mp_subprocess_fd){ + .fd = 0, + .src_fd = -1, + .on_write = subprocess_write, + .on_write_ctx = &fdctx[0], + .write_buf = &stdin_data, + }; + } struct mp_subprocess_result sres; mp_subprocess2(&opts, &sres); @@ -6078,6 +6101,8 @@ const struct mp_cmd_def mp_cmds[] = { {"capture_stderr", OPT_FLAG(v.i), .flags = MP_CMD_OPT_ARG}, {"detach", OPT_FLAG(v.i), .flags = MP_CMD_OPT_ARG}, {"env", OPT_STRINGLIST(v.str_list), .flags = MP_CMD_OPT_ARG}, + {"stdin_data", OPT_STRING(v.s), .flags = MP_CMD_OPT_ARG}, + {"passthrough_stdin", OPT_FLAG(v.i), .flags = MP_CMD_OPT_ARG}, }, .spawn_thread = true, .can_abort = true, -- cgit v1.2.3