diff --git a/syscall/lfs.lua b/syscall/lfs.lua index 7eb1343e..b8e61c95 100644 --- a/syscall/lfs.lua +++ b/syscall/lfs.lua @@ -46,25 +46,36 @@ local attributes = { blksize = "blksize", } -local function attr(st, aname) - if aname then - aname = attributes[aname] - return st[aname] +local function workaround_luafilesystem_compat_device(result, request_name) + if (request_name=="dev" or request_name=="rdev") then + if pcall(function() return result.device end) then + return result.device + end end - local ret = {} - for k, v in pairs(attributes) do ret[k] = st[v] end + return result +end + +local function attr(st, arg) + if type(arg)=="string" then + -- arg is the request_name + arg = attributes[arg] + return workaround_luafilesystem_compat_device(st[arg], arg) + end + -- arg is the result_table + local ret = arg or {} + for k, v in pairs(attributes) do ret[k] = workaround_luafilesystem_compat_device(st[v], v) end return ret end -function lfs.attributes(filepath, aname) +function lfs.attributes(filepath, request_name_or_result_table) local st, err = S.stat(filepath) if not st then return nil, tostring(err) end - return attr(st, aname) + return attr(st, request_name_or_result_table) end -function lfs.symlinkattributes(filepath, aname) +function lfs.symlinkattributes(filepath, request_name_or_result_table) local st, err = S.lstat(filepath) if not st then return nil, tostring(err) end - return attr(st, aname) + return attr(st, request_name_or_result_table) end lfs.chdir = lfswrap(S.chdir) @@ -92,7 +103,7 @@ local function dir_next(dir) dir.di, err = dir.fd:getdents(dir.buf, dir.size) if not dir.di then dir_close(dir) - error(tostring(err)) -- not sure how we are suppose to handle errors + return nil, tostring(err) end dir.first = true end @@ -113,7 +124,9 @@ function lfs.dir(path) local size = 4096 local buf = S.t.buffer(size) local fd, err = S.open(path, "directory, rdonly") - if err then return nil, tostring(err) end + if err then + error("cannot open "..tostring(path)..": "..tostring(err), 2) + end return dir_next, {size = size, buf = buf, fd = fd, next = dir_next, close = dir_close} end diff --git a/test2/test.lfs.device.lua b/test2/test.lfs.device.lua new file mode 100644 index 00000000..3a2166ed --- /dev/null +++ b/test2/test.lfs.device.lua @@ -0,0 +1,16 @@ +#! /usr/bin/env luajit + +local function testwith(lfs, target) + local x = lfs.attributes("/") + assert(type(x.dev)=="number") + assert(type(x.rdev)=="number") + if target then + local y = lfs.symlinkattributes(target) + assert(type(y.dev)=="number") + assert(type(y.rdev)=="number") + end +end +local target = arg[1] +testwith( require"lfs", target ) +testwith( require"syscall.lfs", target ) +print("ok") diff --git a/test2/test.lfs.dir.lua b/test2/test.lfs.dir.lua new file mode 100644 index 00000000..3be50ed6 --- /dev/null +++ b/test2/test.lfs.dir.lua @@ -0,0 +1,29 @@ +#! /usr/bin/env luajit + +local function safe_lfs_dir(lfs_dir, dir) + local f, k + local ok, err = pcall(function() f,k = lfs_dir(dir) end) + if not ok or not f then + print("safe_lfs_dir: catched error:", err) + return function()end + end + return f, k +end + +local function testwith(lfs, target) + local success = true + local count = 0 + for f in safe_lfs_dir(lfs.dir, target) do + count = count+1 + print(count, f) + end + local ok, err = pcall(function() return lfs.dir("/nonexistant") end) + if ok then + print("error should be raised") + success = false + end + return success +end +local target = arg[1] or "/" +if not testwith(require"lfs", target) then print("lfs failure") end +if not testwith(require"syscall.lfs", target) then print("syscall.lfs failure") end