From 03c70a8d81f14ce46bc3410b08f5956d6af34d82 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 27 Jun 2015 21:08:55 +0200 Subject: subprocess, lua: export whether the process was killed by us We want to distinguish actual errors, and just aborting the program intentionally. Also be a bit more careful with handling the wait() exit status: do not called WEXITSTATUS() without checking WIFEXITED() first. --- DOCS/man/lua.rst | 4 ++++ osdep/subprocess-posix.c | 13 ++++++++++--- osdep/subprocess-win.c | 1 + osdep/subprocess.h | 2 ++ player/lua.c | 2 ++ 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst index c52e95c388..d51a6d95c5 100644 --- a/DOCS/man/lua.rst +++ b/DOCS/man/lua.rst @@ -630,6 +630,10 @@ strictly part of the guaranteed API. 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``. + In all cases, ``mp.resume_all()`` is implicitly called. ``utils.parse_json(str [, trail])`` diff --git a/osdep/subprocess-posix.c b/osdep/subprocess-posix.c index b0b4b3663e..16f9735fe7 100644 --- a/osdep/subprocess-posix.c +++ b/osdep/subprocess-posix.c @@ -64,6 +64,8 @@ int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, int p_stderr[2] = {-1, -1}; int devnull = -1; pid_t pid = -1; + bool spawned = false; + bool killed_by_us = false; if (on_stdout && mp_make_cloexec_pipe(p_stdout) < 0) goto done; @@ -89,6 +91,7 @@ int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, pid = -1; goto done; } + spawned = true; close(p_stdout[1]); p_stdout[1] = -1; @@ -124,6 +127,7 @@ int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, } if (fds[2].revents) { kill(pid, SIGKILL); + killed_by_us = true; break; } } @@ -143,12 +147,15 @@ done: close(p_stderr[1]); close(devnull); - if (WIFEXITED(status) && WEXITSTATUS(status) != 127) { + if (!spawned || (WIFEXITED(status) && WEXITSTATUS(status) == 127)) { + *error = "init"; + status = -1; + } else if (WIFEXITED(status)) { *error = NULL; status = WEXITSTATUS(status); } else { - *error = WEXITSTATUS(status) == 127 ? "init" : "killed"; - status = -1; + *error = "killed"; + status = killed_by_us ? MP_SUBPROCESS_EKILLED_BY_US : -1; } return status; diff --git a/osdep/subprocess-win.c b/osdep/subprocess-win.c index a5be9e52ab..3f0330958b 100644 --- a/osdep/subprocess-win.c +++ b/osdep/subprocess-win.c @@ -357,6 +357,7 @@ int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, if (pi.hProcess) { TerminateProcess(pi.hProcess, 1); *error = "killed"; + status = MP_SUBPROCESS_EKILLED_BY_US; goto done; } break; diff --git a/osdep/subprocess.h b/osdep/subprocess.h index 1bd5afe1f8..33c4013f6d 100644 --- a/osdep/subprocess.h +++ b/osdep/subprocess.h @@ -28,6 +28,8 @@ typedef void (*subprocess_read_cb)(void *ctx, char *data, size_t size); int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, subprocess_read_cb on_stdout, subprocess_read_cb on_stderr, char **error); +// mp_subprocess return values. -1 is a generic error code. +#define MP_SUBPROCESS_EKILLED_BY_US -2 struct mp_log; void mp_subprocess_detached(struct mp_log *log, char **args); diff --git a/player/lua.c b/player/lua.c index f640b654cf..5a16c9202a 100644 --- a/player/lua.c +++ b/player/lua.c @@ -1243,6 +1243,8 @@ static int script_subprocess(lua_State *L) 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; } -- cgit v1.2.3