From fe9af338afd6e0ff5eb5131c5f80ad7c5c1e3774 Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Tue, 24 Apr 2018 14:58:32 +0200 Subject: [PATCH] e2lib: fix e2lib.wait() for signaled process wait() returned 0 for a signaled process, expecting the caller to check the third argument for a signal code. Most call sites do not observe the signal argument, leading to "successful" execution of a crashing process. wait() will now return the exit code or signal + 128 in the first argument. This is in line with various shells. Also improve debug logging around wait() and callcmd(). Signed-off-by: Tobias Ulmer --- Changelog | 1 + generic/e2lib.lua | 12 ++++++------ generic/le2lib.c | 26 ++++++++++++++++---------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Changelog b/Changelog index 6225253..a4f1636 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,5 @@ NEXT: + * fix detection of exit status of a signaled process e2factory-2.3.17 * fixed sub-licences handling for file sources diff --git a/generic/e2lib.lua b/generic/e2lib.lua index b895e19..2072302 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -224,7 +224,7 @@ end --- Wait for process to terminate. -- @param pid Process ID, -1 to wait for any child. --- @return Exit status of process (WEXITSTATUS), or false on error. +-- @return Exit status of process, signal + 128, or false on error. -- @return Process ID of the terminated child or error object on failure. -- @return Number of signal that killed the process, if any. function e2lib.wait(pid) @@ -1421,7 +1421,7 @@ function e2lib.callcmd(argv, fdctv, workdir, envdict, nowait) -- start of callcmd() proper - local rc, re, pid + local rc, re, pid, sig local sync_pipes = {} e2lib.logf(4, "calling %q in %q", table.concat(argv, " "), @@ -1496,14 +1496,14 @@ function e2lib.callcmd(argv, fdctv, workdir, envdict, nowait) return pid end - e2lib.logf(4, "waiting for %q", table.concat(argv, " ")) - rc, re = e2lib.wait(pid) + e2lib.logf(4, "waiting for command %s pid %d", table.concat(argv, " "), pid) + rc, re, sig = e2lib.wait(pid) if not rc then return false, re end - e2lib.logf(4, "command %q exit with return code %d", - table.concat(argv, " "), rc) + e2lib.logf(4, "command %q pid %d exit %d signal %d", + table.concat(argv, " "), re, rc, sig or 0) return rc end diff --git a/generic/le2lib.c b/generic/le2lib.c index 17431fd..2f31a76 100644 --- a/generic/le2lib.c +++ b/generic/le2lib.c @@ -287,20 +287,26 @@ process_wait(lua_State *lua) return 2; } - if (!(WIFEXITED(status) || WIFSIGNALED(status))) { - lua_pushboolean(lua, 0); - lua_pushstring(lua, "process terminated(?) due to unknown cause"); - return 2; - } + if (WIFEXITED(status)) { + /* Normal exit case */ + lua_pushnumber(lua, WEXITSTATUS(status)); + lua_pushnumber(lua, rc); - lua_pushnumber(lua, WEXITSTATUS(status)); - lua_pushnumber(lua, rc); - if (WIFSIGNALED(status)) { + return 2; + } else if (WIFSIGNALED(status)) { + /* Signal exit case */ + lua_pushnumber(lua, WTERMSIG(status) + 128); // what dash does + lua_pushnumber(lua, rc); lua_pushnumber(lua, WTERMSIG(status)); + return 3; - } + } else { + /* Job control status but option is unset */ + lua_pushboolean(lua, 0); + lua_pushstring(lua, "internal error, please report (waitpid)"); - return 2; + return 2; + } } static int -- 2.39.5