local plugin = require("plugin")
local tools = require("tools")
local cache = require("cache")
-local luafile = require("luafile")
+local eio = require("eio")
local le2lib = require("le2lib")
-- Module-level global variables
e2lib.closefrom(3)
-- ignore errors, no /proc should not prevent factory from working
- -- Overwrite io functions that create a file descriptor to set the
- -- CLOEXEC flag by default.
- local realopen = io.open
- local realpopen = io.popen
-
- function io.open(...)
- local ret = {realopen(...)} -- closure
- if ret[1] then
- if not luafile.cloexec(ret[1]) then
- return nil, "Setting CLOEXEC failed"
- end
- end
- return unpack(ret)
- end
-
- function io.popen(...)
- local ret = {realpopen(...)} -- closure
- if ret[1] then
- if not luafile.cloexec(ret[1]) then
- return nil, "Setting CLOEXEC failed"
- end
- end
- return unpack(ret)
- end
-
e2lib.globals.warn_category = {
WDEFAULT = false,
WDEPRECATED = false,
end
e2lib.cleanup()
if e2lib.globals.debuglogfile then
- e2lib.globals.debuglogfile:close()
+ eio.fclose(e2lib.globals.debuglogfile)
end
os.exit(returncode)
end
end
end
---- Call a command, connecting stdin, stdout, stderr to luafile
+--- Call a command, connecting stdin, stdout, stderr to EIO
-- 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.
-- redirect stdin
io.stdin:close()
- rc, re = luafile.dup2(luafile.fileno(infile), luafile.STDIN)
+ rc, re = eio.dup2(eio.fileno(infile), eio.STDIN)
if not rc then
e2lib.abort(re)
end
end
-- redirect stdout
io.stdout:close()
- rc, re = luafile.dup2(luafile.fileno(outfile), luafile.STDOUT)
+ rc, re = eio.dup2(eio.fileno(outfile), eio.STDOUT)
if not rc then
e2lib.abort(re)
end
end
-- redirect stderr
io.stderr:close()
- rc, re = luafile.dup2(luafile.fileno(errfile), luafile.STDERR)
+ rc, re = eio.dup2(eio.fileno(errfile), eio.STDERR)
if not rc then
e2lib.abort(re)
end
local input = infile
if not input then
- rc, re = luafile.fopen("/dev/null", "r")
+ rc, re = eio.fopen("/dev/null", "r")
if not rc then
e:cat("input could not be opened")
return false, e:cat(re)
local errin, errout
local pid
- errin, errout = luafile.pipe()
+ errin, errout = eio.pipe()
if not errin then
return false, e:cat(errout)
end
if cmdidx < c then
- pipein, output = luafile.pipe()
+ pipein, output = eio.pipe()
if not pipein then
return false, e:cat(output)
end
elseif pid == 0 then
if cmdidx < c then
-- everyone but the last
- luafile.fclose(pipein)
+ eio.fclose(pipein)
end
- luafile.fclose(errin)
+ eio.fclose(errin)
rc = callcmd(input, output, errout, cmds[cmdidx])
os.exit(rc)
end
pids[pid] = cmdidx
- e2lib.unblock(luafile.fileno(errin))
+ e2lib.unblock(eio.fileno(errin))
ers[cmdidx] = errin
- luafile.fclose(errout)
+ eio.fclose(errout)
-- close all outputs except the last one (outfile)
if cmdidx < c then
- luafile.fclose(output)
+ eio.fclose(output)
end
-- do not close first input (infile)
if cmdidx > 1 or not infile then
- luafile.fclose(input)
+ eio.fclose(input)
end
input = pipein
end
local fds = {}
local ifd = {}
for i, f in pairs(ers) do
- local n = luafile.fileno(f)
+ local n = eio.fileno(f)
table.insert(fds, n)
ifd[n] = i
end
local line
while true do
- line, re = luafile.readline(ers[i])
+ line, re = eio.readline(ers[i])
if not line then
return false, re
elseif line == "" then
end
else
- luafile.fclose(ers[i])
+ eio.fclose(ers[i])
ers[i] = nil
c = c - 1
end
end
capture = capture or autocapture
- oread, owrite = luafile.pipe()
+ oread, owrite = eio.pipe()
if not oread then
return false, owrite
end
- devnull, re = luafile.fopen("/dev/null", "r")
+ devnull, re = eio.fopen("/dev/null", "r")
if not devnull then
return false, re
end
- luafile.setlinebuf(owrite)
- luafile.setlinebuf(oread)
+ eio.setlinebuf(owrite)
+ eio.setlinebuf(oread)
e2lib.logf(4, "+ %s", cmd)
pid, re = e2lib.fork()
if not pid then
return false, re
elseif pid == 0 then
- luafile.fclose(oread)
+ eio.fclose(oread)
rc = callcmd(devnull, owrite, owrite, cmd)
os.exit(rc)
else
- rc, re = luafile.fclose(owrite)
+ rc, re = eio.fclose(owrite)
if not rc then
return false, re
end
local line
while true do
- line, re = luafile.readline(oread)
+ line, re = eio.readline(oread)
if not line then
return false, re
elseif line == "" then
capture(line)
end
- rc, re = luafile.fclose(oread)
+ rc, re = eio.fclose(oread)
if not rc then
return false, re
end
rc, re = e2lib.wait(pid)
if not rc then
- luafile.fclose(devnull)
+ eio.fclose(devnull)
return false, re
end
ret = rc
- luafile.fclose(devnull)
+ eio.fclose(devnull)
end
return ret
function e2lib.parse_e2versionfile(filename)
local f, e, rc, re, l
- f, re = luafile.fopen(filename, "r")
+ f, re = eio.fopen(filename, "r")
if not f then
e = err.new("can't open e2 version file: %s", filename)
return false, e:cat(re)
end
- l, re = luafile.readline(f)
- luafile.fclose(f)
-
+ l, re = eio.readline(f)
+ eio.fclose(f)
if not l then
e = err.new("can't parse e2 version file: %s", filename)
return false, e:cat(re)
---- File handling.
--- @module generic.luafile
+--- Extended IO
+-- @module generic.eio
--[[
e2factory, the emlix embedded build system
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
-local luafile = {}
+local eio = {}
local e2lib = require("e2lib")
local err = require("err")
-local luafile_ll = require("luafile_ll")
+local leio = require("leio")
local strict = require("strict")
--- Numeric constant for stdin.
-luafile.STDIN = 0;
+eio.STDIN = 0;
--- Numeric constant for stdout.
-luafile.STDOUT = 1;
+eio.STDOUT = 1;
--- Numeric constant for sterr.
-luafile.STDERR = 2;
+eio.STDERR = 2;
---- Check whether a luafile object is valid and contains an open file.
--- @param luafile File object.
+--- Check whether an EIO object is valid and contains an open file.
+-- @param file File object.
-- @return True on success, false on error.
-- @return Error object on failure.
-local function valid_open_luafile(luafile)
- local msg = "Internal luafile error: Please report this error:"
+local function is_eio_object(file)
+ local msg = "Internal EIO error: Please report this error:"
- if type(luafile) ~= "table" then
+ if type(file) ~= "table" then
return false, err.new("%s invalid object", msg)
end
- if type(luafile.file) == "boolean" and not luafile.file then
+ if type(file.handle) == "boolean" and not file.handle then
return false,
err.new("%s no open file", msg)
end
- if type(luafile.file) ~= "userdata" then
+ if type(file.handle) ~= "userdata" then
return false, err.new("%s invalid internal field structure")
end
--- Create new file object.
-- @return File object. This function always succeeds.
-function luafile.new()
- local luafile = {}
- luafile.file = false
- return strict.lock(luafile)
+function eio.new()
+ local file = {}
+ file.handle = false
+ return strict.lock(file)
end
--- Open a file.
-- @param mode Mode string of r, r+, w, w+, a or a+. See fopen(3) for details.
-- @return File object on success, false on error.
-- @return Error object on failure.
-function luafile.fopen(path, mode)
- local f, handle, errstring
+function eio.fopen(path, mode)
+ local file, handle, errstring
- handle, errstring = luafile_ll.fopen(path, mode)
+ handle, errstring = leio.fopen(path, mode)
if not handle then
return false, err.new("could not open file %q with mode %q: %s",
path, mode, errstring)
end
- f = luafile.new()
- f.file = handle
- return f
+ file = eio.new()
+ file.handle = handle
+ return file
end
--- Open a file descriptor.
-- @param mode Mode string of r, r+, w, w+, a or a+. See fdopen(3) for details.
-- @return File object on success, false on error.
-- @return Error object on failure.
-function luafile.fdopen(fd, mode)
- local f, handle, errstring
+function eio.fdopen(fd, mode)
+ local file, handle, errstring
- handle, errstring = luafile_ll.fdopen(fd, mode)
+ handle, errstring = leio.fdopen(fd, mode)
if not handle then
return false,
err.new("could not open file descriptor %d with mode %q: %s",
fd, mode, errstring)
end
- f = luafile.new()
- f.file = handle
- return f
+ file = eio.new()
+ file.handle = handle
+ return file
end
--- Close a file object.
--- @param luafile File object.
+-- @param file File object.
-- @return True on success, false on error.
-- @return Error object on failure.
-function luafile.fclose(luafile)
+function eio.fclose(file)
local rc, re, errstring
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
return false, re
end
- rc, errstring = luafile_ll.fclose(luafile.file)
- luafile.file = false
+ rc, errstring = leio.fclose(file.handle)
+ file.handle = false
if not rc then
return false, err.new("error closing file: %s", errstring)
end
end
--- Read a file.
--- @param luafile File object.
+-- @param file File object.
-- @return File data as a string, or false on error. May be up to 16K bytes
-- large and contain embedded zero's. On EOF an empty string is returned.
-- @return Error object on failure.
-function luafile.fread(luafile)
+function eio.fread(file)
local rc, re, errstring, buffer
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
return false, re
end
- buffer, errstring = luafile_ll.fread(luafile.file)
+ buffer, errstring = leio.fread(file.handle)
if not buffer then
return false, err.new("error reading file: %s", errstring)
end
end
--- Read character from file.
--- @param luafile File object.
+-- @param file File object.
-- @return Character as a string, string of length 0 on EOF, or false on error.
-- @return Error object on failure.
-function luafile.fgetc(luafile)
+function eio.fgetc(file)
local rc, re, errstring, char
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
return false, re
end
- char, errstring = luafile_ll.fgetc(luafile.file)
+ char, errstring = leio.fgetc(file.handle)
if not char then
return false, err.new("error reading character from file: %s",
errstring)
end
--- Write buffer to a file.
--- @param luafile File object.
+-- @param file File object.
-- @param buffer Data string to be written. May contain embedded zero's.
-- @return True on success, False on error.
-- @return Error object on failure.
-function luafile.fwrite(luafile, buffer)
+function eio.fwrite(file, buffer)
local rc, re, errstring
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
return false, rc
end
- rc, errstring = luafile_ll.fwrite(luafile.file, buffer)
+ rc, errstring = leio.fwrite(file.handle, buffer)
if not rc then
return false, err.new("error writing file: %s", errstring)
end
-- but no further. Returns the empty string on end-of-file, or false in
-- case of an error.
-- @return Error object on failure.
-function luafile.readline(file)
+function eio.readline(file)
local rc, re, line, char
- --rc, re = valid_open_luafile(file)
+ --rc, re = is_eio_object(file)
--if not rc then
-- return false, rc
--end
line = ""
while true do
- char, re = luafile.fgetc(file)
+ char, re = eio.fgetc(file)
if not char then
return false, re
elseif char == "\0" then
end
--- Return file descriptor of a file object.
--- @param luafile File object.
+-- @param file File object.
-- @return Integer file descriptor of the file descriptor. This method does not
-- have an error condition. If passed an invalid or closed file object, it calls
-- e2lib.abort() signaling an internal error.
-function luafile.fileno(luafile)
+function eio.fileno(file)
local rc, re, fd, errstring
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
e2lib.abort(re)
end
- fd, errstring = luafile_ll.fileno(luafile.file)
+ fd, errstring = leio.fileno(file.handle)
if not fd then
e2lib.abort(err.new("%s", errstring))
end
end
--- Test for end of file.
--- @param luafile File object.
+-- @param file File object.
-- @return True on end-of-file, false otherwise. feof calls
-- e2lib.abort() when used with an invalid file object.
-function luafile.feof(luafile)
+function eio.feof(file)
local rc, re
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
e2lib.abort(re)
end
- rc, re = luafile_ll.feof(luafile.file)
+ rc, re = leio.feof(file.handle)
if not rc and re then
e2lib.abort(err.new("%s", re))
end
--- Enable line buffer mode. See setbuf(3) for details. setlinebuf has no
-- error conditions. If an invalid file object is passed, it calls
-- e2lib.abort() terminating the process.
--- @param luafile File object
-function luafile.setlinebuf(luafile)
+-- @param file File object
+function eio.setlinebuf(file)
local errstring, rc, re
- rc, re = valid_open_luafile(luafile)
+ rc, re = is_eio_object(file)
if not rc then
e2lib.abort(re)
end
- rc, errstring = luafile_ll.setlinebuf(luafile.file)
+ rc, errstring = leio.setlinebuf(file.handle)
if not rc then
e2lib.abort(err.new("%s", errstring))
end
-- before the call, it's closed automatically.
-- @return True on success, false on error.
-- @return Error object on failure.
-function luafile.dup2(oldfd, newfd)
+function eio.dup2(oldfd, newfd)
local rc, errstring
- rc, errstring = luafile_ll.dup2(oldfd, newfd)
+ rc, errstring = leio.dup2(oldfd, newfd)
if not rc then
return false,
err.new("duplicating file descriptor failed: %s", errstring)
--- Create a new UNIX pipe(2) between two file objects.
-- @return File object in read mode, or false on error.
-- @return File object in write mode, or error object on failure.
-function luafile.pipe()
+function eio.pipe()
local fd1, fd2, fr, fw, re
- fd1, fd2 = luafile_ll.pipe()
+ fd1, fd2 = leio.pipe()
if not fd1 then
return false, err.new("failed creating pipe: %s", fd2)
end
- fr, re = luafile.fdopen(fd1, "r")
+ fr, re = eio.fdopen(fd1, "r")
if not fr then
return false, re
end
- fw,re = luafile.fdopen(fd2, "w")
+ fw,re = eio.fdopen(fd2, "w")
if not fw then
return false, re
end
--- Set the CLOEXEC flag on underlying file descriptor. Throws exception on
-- invalid input.
--- @param something can be a file descriptor number, luafile object, or io file
+-- @param something can be a numeric file descriptor, eio file, or io file
-- @param set True to set the CLOEXEC, False to unset it. Defaults to True.
-- @return True on success, False on error.
-function luafile.cloexec(something, set)
+function eio.cloexec(something, set)
assert(something ~= nil)
assert(set == nil or type(set) == "boolean")
if set == nil then
set = true
end
- return luafile_ll.cloexec(something, set)
+ return leio.cloexec(something, set)
end
-return strict.lock(luafile)
+return strict.lock(eio)
-- vim:sw=4:sts=4:et:
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- Low-level file-system and process operations.
-*/
-
-#include <errno.h>
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int
-lua_fopen(lua_State *lua)
+eio_fopen(lua_State *lua)
{
FILE *f;
const char *file, *mode;
}
static int
-lua_fclose(lua_State *lua)
+eio_fclose(lua_State *lua)
{
FILE *f;
if (f == NULL) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
- "lua_fclose: one or more arguments of wrong type/missing");
+ "eio_fclose: one or more arguments of wrong type/missing");
return 2;
}
}
static int
-lua_fdopen(lua_State *lua)
+eio_fdopen(lua_State *lua)
{
FILE *f;
int fd;
}
static int
-lua_fwrite(lua_State *lua)
+eio_fwrite(lua_State *lua)
{
FILE *f;
const char *b;
if (f == NULL || b == NULL) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
- "lua_fwrite: one or more arguments of wrong type/missing");
+ "eio_fwrite: one or more arguments of wrong type/missing");
return 2;
}
/* What does end of file on write mean?
* Signal an error */
lua_pushboolean(lua, 0);
- lua_pushstring(lua, "lua_fwrite: end of file");
+ lua_pushstring(lua, "eio_fwrite: end of file");
return 2;
}
}
}
static int
-lua_fread(lua_State *lua)
+eio_fread(lua_State *lua)
{
char buf[16384];
size_t ret;
if (f == NULL) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
- "lua_fread: one or more arguments of wrong type/missing");
+ "eio_fread: one or more arguments of wrong type/missing");
return 2;
}
}
static int
-lua_fgetc(lua_State *L)
+eio_fgetc(lua_State *L)
{
FILE *f;
int c;
if (f == NULL) {
lua_pushboolean(L, 0);
lua_pushstring(L,
- "lua_fgetc: argument of wrong type or missing");
+ "eio_fgetc: argument of wrong type or missing");
return 2;
}
}
static int
-lua_pipe(lua_State *L)
+eio_pipe(lua_State *L)
{
int fd[2];
int rc;
}
static int
-lua_fileno(lua_State *lua)
+eio_fileno(lua_State *lua)
{
FILE *f;
int fd;
if (f == NULL) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
- "lua_fileno: one or more arguments of wrong type/missing");
+ "eio_fileno: one or more arguments of wrong type/missing");
return 2;
}
fd = fileno(f);
}
static int
-lua_feof(lua_State *lua)
+eio_feof(lua_State *lua)
{
FILE *f;
if (f == NULL) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
- "lua_feof: arguments wrong type or missing");
+ "eio_feof: arguments wrong type or missing");
return 2;
}
}
static int
-lua_setlinebuf(lua_State *lua)
+eio_setlinebuf(lua_State *lua)
{
FILE *f;
f = lua_touserdata(lua, 1);
if (!f) {
lua_pushboolean(lua, 0);
- lua_pushstring(lua, "lua_setlinebuf: one or more arguments "
+ lua_pushstring(lua, "eio_setlinebuf: one or more arguments "
"of wrong type/missing");
return 2;
}
}
static int
-lua_dup2(lua_State *lua)
+eio_dup2(lua_State *lua)
{
int oldfd, newfd, rc;
}
static int
-lua_cloexec(lua_State *lua)
+eio_cloexec(lua_State *lua)
{
int fd = -1, rc, cloexec;
FILE *f = NULL;
if (lua_isnumber(lua, 1)) {
fd = luaL_checkint(lua, 1);
} else if (lua_istable(lua, 1)) {
- lua_pushstring(lua, "file"); // key
+ lua_pushstring(lua, "handle"); // key
lua_gettable(lua, 1);
if (!lua_islightuserdata(lua, -1))
- luaL_argerror(lua, 1, "not a luafile table");
+ luaL_argerror(lua, 1, "not a eio table");
f = (FILE *)lua_topointer(lua, -1);
} else if (lua_isuserdata(lua, 1)) {
FILE **p;
}
if (fd < 0) {
- luaL_argerror(lua, 1, "fd/luafile/io file required");
+ luaL_argerror(lua, 1, "fd/eio/io file required");
}
if (lua_isboolean(lua, 2)) {
}
static luaL_Reg lib[] = {
- { "fopen", lua_fopen },
- { "fdopen", lua_fdopen },
- { "fclose", lua_fclose },
- { "fwrite", lua_fwrite },
- { "fread", lua_fread },
- { "fgetc", lua_fgetc },
- { "pipe", lua_pipe },
- { "setlinebuf", lua_setlinebuf },
- { "feof", lua_feof },
- { "fileno", lua_fileno },
- { "dup2", lua_dup2 },
- { "cloexec", lua_cloexec },
+ { "cloexec", eio_cloexec },
+ { "dup2", eio_dup2 },
+ { "fclose", eio_fclose },
+ { "fdopen", eio_fdopen },
+ { "feof", eio_feof },
+ { "fgetc", eio_fgetc },
+ { "fileno", eio_fileno },
+ { "fopen", eio_fopen },
+ { "fread", eio_fread },
+ { "fwrite", eio_fwrite },
+ { "pipe", eio_pipe },
+ { "setlinebuf", eio_setlinebuf },
{ NULL, NULL }
};
int
-luaopen_luafile_ll(lua_State *lua)
+luaopen_leio(lua_State *lua)
{
luaL_Reg *next;