From 5f1b02cab9cef951a947cc9dc27ab12c37b1ad6b Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Wed, 23 Oct 2013 18:00:45 +0200 Subject: [PATCH] Use new luafile API and check for errors in more places Signed-off-by: Tobias Ulmer --- generic/e2lib.lua | 168 ++++++++++++++++++++++++++++++---------------- local/e2build.lua | 14 ++-- 2 files changed, 119 insertions(+), 63 deletions(-) diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 8503bc8..48e0f11 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -1145,29 +1145,48 @@ function e2lib.directory(path, dotfiles, noerror) end end ---- callcmd: call a command, connecting --- stdin, stdout, stderr to luafile objects. +--- Call a command, connecting stdin, stdout, stderr to luafile +-- objects. This function is running in the child process. It may call +-- e2lib.abort() in case of error, which should be caught by the parent +-- process. +-- @param infile File object to be used as stdin. +-- @param outfile File object to be used as stdout. +-- @param errfile File object to be used as stderr. +-- @param cmd Command string, passed to os.execute(). +-- @return Return code (number) in case of os.execute() failure. This function +-- does not return on success. local function callcmd(infile, outfile, errfile, cmd) + local rc, re + -- redirect stdin io.stdin:close() - luafile.dup2(infile:fileno(), 0) - if infile:fileno() ~= 0 then - infile:cloexec() + rc, re = luafile.dup2(luafile.fileno(infile), luafile.STDIN) + if not rc then + e2lib.abort(re) + end + if luafile.fileno(infile) ~= 0 then + luafile.cloexec(infile) end -- redirect stdout io.stdout:close() - luafile.dup2(outfile:fileno(), 1) - if outfile:fileno() ~= 1 then - outfile:cloexec() + rc, re = luafile.dup2(luafile.fileno(outfile), luafile.STDOUT) + if not rc then + e2lib.abort(re) + end + if luafile.fileno(outfile) ~= 1 then + luafile.cloexec(outfile) end -- redirect stderr io.stderr:close() - luafile.dup2(errfile:fileno(), 2) - if errfile:fileno() ~= 2 then - errfile:cloexec() + rc, re = luafile.dup2(luafile.fileno(errfile), luafile.STDERR) + if not rc then + e2lib.abort(re) + end + if luafile.fileno(errfile) ~= 2 then + luafile.cloexec(errfile) end -- run the command - local rc = os.execute(cmd) + rc = os.execute(cmd) return (rc/256) end @@ -1181,9 +1200,15 @@ function e2lib.callcmd_pipe(cmds, infile, outfile) local e = err.new("calling commands in a pipe failed") local rc, re - local input = infile or luafile.open("/dev/null", "r") + local input = infile + if not input then - return false, e:cat("input could not be opened") + rc, re = luafile.fopen("/dev/null", "r") + if not rc then + e:cat("input could not be opened") + return false, e:cat(re) + end + input = rc end local rcs = {} @@ -1200,15 +1225,15 @@ function e2lib.callcmd_pipe(cmds, infile, outfile) local errin, errout local pid - rc, errin, errout = luafile.pipe() - if not rc then - return false, err.new("failed to open error pipe") + errin, errout = luafile.pipe() + if not errin then + return false, e:cat(errout) end if cmdidx < c then - rc , pipein, output = luafile.pipe() - if not rc then - return false, err.new("failed to open pipe") + pipein, output = luafile.pipe() + if not pipein then + return false, e:cat(output) end else -- last command in pipe @@ -1222,27 +1247,27 @@ function e2lib.callcmd_pipe(cmds, infile, outfile) elseif pid == 0 then if cmdidx < c then -- everyone but the last - pipein:close() + luafile.fclose(pipein) end - errin:close() + luafile.fclose(errin) rc = callcmd(input, output, errout, cmds[cmdidx]) os.exit(rc) end pids[pid] = cmdidx - e2lib.unblock(errin:fileno()) + e2lib.unblock(luafile.fileno(errin)) ers[cmdidx] = errin - errout:close() + luafile.fclose(errout) -- close all outputs except the last one (outfile) if cmdidx < c then - output:close() + luafile.fclose(output) end -- do not close first input (infile) if cmdidx > 1 or not infile then - input:close() + luafile.fclose(input) end input = pipein end @@ -1251,7 +1276,7 @@ function e2lib.callcmd_pipe(cmds, infile, outfile) local fds = {} local ifd = {} for i, f in pairs(ers) do - local n = f:fileno() + local n = luafile.fileno(f) table.insert(fds, n) ifd[n] = i end @@ -1263,17 +1288,21 @@ function e2lib.callcmd_pipe(cmds, infile, outfile) i = ifd[fds[i]] if r then - local x - - repeat - x = ers[i]:readline() - if x then - e2lib.log(3, x) + local line + + while true do + line, re = luafile.readline(ers[i]) + if not line then + return false, re + elseif line == "" then + break end - until not x + + e2lib.log(3, line) + end else - ers[i]:close() + luafile.fclose(ers[i]) ers[i] = nil c = c - 1 end @@ -1317,47 +1346,67 @@ end -- @return Return status code of the command (number) or false on error. -- @return Error object on failure. function e2lib.callcmd_capture(cmd, capture) - local rc, re, oread, owrite, devnull, pid + local rc, re, oread, owrite, devnull, pid, ret local function autocapture(msg) e2lib.log(3, msg) end capture = capture or autocapture - rc, oread, owrite = luafile.pipe() - owrite:setlinebuf() - oread:setlinebuf() - devnull = luafile.open("/dev/null", "r") + oread, owrite = luafile.pipe() + if not oread then + return false, owrite + end + devnull, re = luafile.fopen("/dev/null", "r") if not devnull then - e2lib.abort("could not open /dev/null") + return false, re end + + luafile.setlinebuf(owrite) + luafile.setlinebuf(oread) + e2lib.logf(4, "+ %s", cmd) pid, re = e2lib.fork() if not pid then return false, re elseif pid == 0 then - oread:close() + luafile.fclose(oread) rc = callcmd(devnull, owrite, owrite, cmd) os.exit(rc) else - owrite:close() - while not oread:eof() do - local x = oread:readline() - if x then - capture(x) + rc, re = luafile.fclose(owrite) + if not rc then + return false, re + end + + local line + while true do + line, re = luafile.readline(oread) + if not line then + return false, re + elseif line == "" then + break end + + capture(line) end - oread:close() + + rc, re = luafile.fclose(oread) + if not rc then + return false, re + end + rc, re = e2lib.wait(pid) if not rc then - luafile.close(devnull) + luafile.fclose(devnull) return false, re end + ret = rc - luafile.close(devnull) + luafile.fclose(devnull) end - return rc + return ret end --- Call a command, log its output and catch the last lines for error reporting. @@ -1384,7 +1433,7 @@ function e2lib.callcmd_log(cmd) local rc, re = e2lib.callcmd_capture(cmd, logto) if not rc then - return false, e:cat(e) + return false, e:cat(re) end if #fifo == 0 then @@ -1530,15 +1579,20 @@ end -- @return Table containing tag and branch. False on error. -- @return Error object on failure. function e2lib.parse_e2versionfile(filename) - local f = luafile.open(filename, "r") + local f, e, rc, re, l + + f, re = luafile.fopen(filename, "r") if not f then - return false, err.new("can't open e2version file: %s", filename) + e = err.new("can't open e2 version file: %s", filename) + return false, e:cat(re) end - local l = f:readline() - f:close() + l, re = luafile.readline(f) + luafile.fclose(f) + if not l then - return false, err.new("can't parse e2version file: %s", filename) + e = err.new("can't parse e2 version file: %s", filename) + return false, e:cat(re) end local match = l:gmatch("[^%s]+") diff --git a/local/e2build.lua b/local/e2build.lua index cc95e50..f7d7999 100644 --- a/local/e2build.lua +++ b/local/e2build.lua @@ -290,18 +290,20 @@ local function setup_chroot(info, r, return_flags) return false, e:cat(re) end - local cm = luafile.open(res.build_config.chroot_marker, "w") - if not cm then - re = err.new("could not create chroot marker") + rc, re = luafile.fopen(res.build_config.chroot_marker, "w") + if not rc then return false, e:cat(re) end - if not luafile.close(cm) then - re = err.new("failed to close chroot marker file") + + local cm = rc + + rc, re = luafile.fclose(cm) + if not rc then return false, e:cat(re) end e2tool.set_umask(info) - local rc, re = e2lib.e2_su_2_2({"set_permissions_2_3", res.build_config.base}) + rc, re = e2lib.e2_su_2_2({"set_permissions_2_3", res.build_config.base}) e2tool.reset_umask(info) if not rc then return false, e:cat(re) -- 2.39.5