summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/lua.rst56
-rw-r--r--player/command.c2
-rw-r--r--player/lua.c78
-rw-r--r--player/lua/defaults.lua23
4 files changed, 41 insertions, 118 deletions
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index dab185a284..ba09164d3b 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -653,45 +653,23 @@ strictly part of the guaranteed API.
``utils.subprocess(t)``
Runs an external process and waits until it exits. Returns process status
- and the captured output.
-
- The parameter ``t`` is a table. The function reads the following entries:
-
- ``args``
- Array of strings. The first array entry is the executable. This
- can be either an absolute path, or a filename with no path
- components, in which case the ``PATH`` environment variable is
- used to resolve the executable. The other array elements are
- passed as command line arguments.
-
- ``cancellable``
- Optional. If set to ``true`` (default), then if the user stops
- playback or goes to the next file while the process is running,
- the process will be killed.
-
- ``max_size``
- Optional. The maximum size in bytes of the data that can be captured
- from stdout. (Default: 16 MB.)
-
- The function returns a table as result with the following entries:
-
- ``status``
- The raw exit status of the process. It will be negative on error.
-
- ``stdout``
- Captured output stream as string, limited to ``max_size``.
-
- ``error``
- ``nil`` on success. The string ``killed`` if the process was
- terminated in an unusual way. The string ``init`` if the process
- could not be started.
-
- On Windows, ``killed`` is only returned when the process has been
- killed by mpv as a result of ``cancellable`` being set to ``true``.
-
- ``killed_by_us``
- Set to ``true`` if the process has been killed by mpv as a result
- of ``cancellable`` being set to ``true``.
+ and the captured output. This is a legacy wrapper around calling the
+ ``subprocess`` command with ``mp.command_native``. It does the following
+ things:
+
+ - copy the table ``t``
+ - rename ``cancellable`` field to ``playback_only``
+ - rename ``max_size`` to ``capture_size``
+ - set ``capture_stdout`` field to ``true`` if unset
+ - set ``name`` field to ``subprocess``
+ - call ``mp.command_native(copied_t)``
+ - if the command failed, create a dummy result table
+ - copy ``error_string`` to ``error`` field if the string is non-empty
+ - return the result table
+
+ It is recommended to use ``mp.command_native`` or ``mp.command_native_async``
+ directly, instead of calling this legacy wrapper. It is for compatibility
+ only.
``utils.subprocess_detached(t)``
Runs an external process and detaches it from mpv's control.
diff --git a/player/command.c b/player/command.c
index fe6c3fd2ca..f2d7eedd5f 100644
--- a/player/command.c
+++ b/player/command.c
@@ -5680,7 +5680,7 @@ static void cmd_subprocess(void *p)
void *tmp = talloc_new(NULL);
struct subprocess_cb_ctx ctx = {
- .log = mpctx->log,
+ .log = mp_log_new(tmp, mpctx->log, cmd->cmd->sender),
.talloc_ctx = tmp,
.max_size = cmd->args[2].v.i,
.capture = {0, cmd->args[3].v.i, cmd->args[4].v.i},
diff --git a/player/lua.c b/player/lua.c
index 8d4e794a52..f3bc3e699b 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -1187,83 +1187,6 @@ static int script_join_path(lua_State *L)
return 1;
}
-struct subprocess_cb_ctx {
- struct mp_log *log;
- void* talloc_ctx;
- int64_t max_size;
- bstr output;
-};
-
-static void subprocess_stdout(void *p, char *data, size_t size)
-{
- struct subprocess_cb_ctx *ctx = p;
- if (ctx->output.len < ctx->max_size)
- bstr_xappend(ctx->talloc_ctx, &ctx->output, (bstr){data, size});
-}
-
-static void subprocess_stderr(void *p, char *data, size_t size)
-{
- struct subprocess_cb_ctx *ctx = p;
- MP_INFO(ctx, "%.*s", (int)size, data);
-}
-
-static int script_subprocess(lua_State *L)
-{
- struct script_ctx *ctx = get_ctx(L);
- luaL_checktype(L, 1, LUA_TTABLE);
- void *tmp = mp_lua_PITA(L);
-
- lua_getfield(L, 1, "args"); // args
- int num_args = mp_lua_len(L, -1);
- char *args[256];
- if (num_args > MP_ARRAY_SIZE(args) - 1) // last needs to be NULL
- luaL_error(L, "too many arguments");
- if (num_args < 1)
- luaL_error(L, "program name missing");
- for (int n = 0; n < num_args; n++) {
- lua_pushinteger(L, n + 1); // args n
- lua_gettable(L, -2); // args arg
- args[n] = talloc_strdup(tmp, lua_tostring(L, -1));
- if (!args[n])
- luaL_error(L, "program arguments must be strings");
- lua_pop(L, 1); // args
- }
- args[num_args] = NULL;
- lua_pop(L, 1); // -
-
- lua_getfield(L, 1, "cancellable"); // c
- struct mp_cancel *cancel = NULL;
- if (lua_isnil(L, -1) ? true : lua_toboolean(L, -1))
- cancel = ctx->mpctx->playback_abort;
- lua_pop(L, 1); // -
-
- lua_getfield(L, 1, "max_size"); // m
- int64_t max_size = lua_isnil(L, -1) ? 64 * 1024 * 1024 : lua_tointeger(L, -1);
-
- struct subprocess_cb_ctx cb_ctx = {
- .log = ctx->log,
- .talloc_ctx = tmp,
- .max_size = max_size,
- };
-
- char *error = NULL;
- int status = mp_subprocess(args, cancel, &cb_ctx, subprocess_stdout,
- subprocess_stderr, &error);
-
- lua_newtable(L); // res
- if (error) {
- lua_pushstring(L, error); // res e
- lua_setfield(L, -2, "error"); // res
- }
- lua_pushinteger(L, status); // res s
- lua_setfield(L, -2, "status"); // res
- lua_pushlstring(L, cb_ctx.output.start, cb_ctx.output.len); // res d
- lua_setfield(L, -2, "stdout"); // res
- lua_pushboolean(L, status == MP_SUBPROCESS_EKILLED_BY_US); // res b
- lua_setfield(L, -2, "killed_by_us"); // res
- return 1;
-}
-
static int script_subprocess_detached(lua_State *L)
{
struct script_ctx *ctx = get_ctx(L);
@@ -1386,7 +1309,6 @@ static const struct fn_entry utils_fns[] = {
FN_ENTRY(file_info),
FN_ENTRY(split_path),
FN_ENTRY(join_path),
- FN_ENTRY(subprocess),
FN_ENTRY(subprocess_detached),
FN_ENTRY(getpid),
FN_ENTRY(parse_json),
diff --git a/player/lua/defaults.lua b/player/lua/defaults.lua
index 6f5a9c4b6c..feb400111a 100644
--- a/player/lua/defaults.lua
+++ b/player/lua/defaults.lua
@@ -617,4 +617,27 @@ function mp_utils.format_bytes_humanized(b)
return string.format("%0.2f %s", b, d[i] and d[i] or "*1024^" .. (i-1))
end
+function mp_utils.subprocess(t)
+ local cmd = {}
+ cmd.name = "subprocess"
+ cmd.capture_stdout = true
+ for k, v in pairs(t) do
+ if k == "cancellable" then
+ k = "playback_only"
+ elseif k == "max_size" then
+ k = "capture_size"
+ end
+ cmd[k] = v
+ end
+ local res, err = mp.command_native(cmd)
+ if res == nil then
+ -- an error usually happens only if parsing failed (or no args passed)
+ res = {error_string = err, status = -1}
+ end
+ if res.error_string ~= "" then
+ res.error = res.error_string
+ end
+ return res
+end
+
return {}