Commit e79e5c5c authored by Karel Koci's avatar Karel Koci 🤘

Add lstat function to lua interpreter

In previous implementation lstat could been called from lua via
appending another argument to stat. Instead of that we have now lstat as
function directly in lua, and previous additional boolean argument is
now C function argument. Probably better would be to use C closures, but
this would add too much complications and would be currently used only
by one function. In future it might be better to use closures if more
such functions were implemented.
parent 327aa502
......@@ -41,6 +41,7 @@ local chdir = chdir
local run_command = run_command
local events_wait = events_wait
local stat = stat
local lstat = lstat
local mkdir = mkdir
local move = move
local ls = ls
......@@ -670,7 +671,7 @@ function pkg_merge_files(dir, dirs, files, configs)
Now move all the files in place.
for f in pairs(files) do
if stat(dir .. f, true) == nil then
if lstat(dir .. f) == nil then
DBG("File " .. f .. " already installed")
DBG("Installing file " .. f)
......@@ -764,7 +765,7 @@ function pkg_cleanup_files(files, rm_configs)
local ok, err = pcall(function () os.remove(path) end)
-- If it failed because the file didn't exist, that's OK. Mostly.
if not ok then
local tp = stat(path, true)
local tp = lstat(path)
if tp then
......@@ -587,12 +587,11 @@ static const char *perm2str(struct stat *buf) {
return perm;
static int lua_stat(lua_State *L) {
static int stat_lstat(lua_State *L, bool use_lstat) {
const char *fname = luaL_checkstring(L, 1);
struct stat buf;
int result;
if (lua_toboolean(L, 2))
// Use lstat instead of stat. Non-existent parameter is OK with lua_toboolean (and returns false)
if (use_lstat)
result = lstat(fname, &buf);
result = stat(fname, &buf);
......@@ -608,6 +607,14 @@ static int lua_stat(lua_State *L) {
return 2;
static int lua_stat(lua_State *L) {
return stat_lstat(L, false);
static int lua_lstat(lua_State *L) {
return stat_lstat(L, true);
static int lua_sync(lua_State *L __attribute__((unused))) {
......@@ -694,6 +701,7 @@ static const struct injected_func injected_funcs[] = {
{ lua_move, "move" },
{ lua_ls, "ls" },
{ lua_stat, "stat" },
{ lua_lstat, "lstat" },
{ lua_sync, "sync" },
{ lua_setenv, "setenv" },
{ lua_md5, "md5" },
......@@ -131,12 +131,14 @@ ls(directory)::
s;; A unix-domain socket
?;; Failed to determine the type
stat(path, [lstat])::
Statistics about the given file. If the file does not exist, it
returns nothing. Otherwise, the file type is returned (see the types
of `ls`). The second result is the permissions of the file, in the
imitation of shell's `ls -l`, like `rwxr-x---`. If the second
parameter is set to true value, the `lstat` behaviour is preferred
imitation of shell's `ls -l`, like `rwxr-x---`.
Same as `stat` except the `lstat` behaviour is preferred.
(eg. provides info about symbolic link if it is a link, instead of
the target).
......@@ -54,10 +54,10 @@ function test_fsutils()
assert_equal("d", stat_type)
assert_equal("rwxr-x---", stat_perm)
-- Check the symbolic link stat version
stat_type, stat_perm = stat(dir .. "/s1", true)
stat_type, stat_perm = lstat(dir .. "/s1")
assert_equal("l", stat_type)
assert_equal("rwxrwxrwx", stat_perm)
stat_type, stat_perm = stat(dir .. "/d1", true)
stat_type, stat_perm = lstat(dir .. "/d1")
assert_equal("d", stat_type)
assert_equal("rwxr-x---", stat_perm)
-- Doesn't exist
......@@ -69,7 +69,7 @@ function test_fsutils()
move(dir .. "/d1", dir .. "/d2")
assert_table_equal({["d2"] = "d", ["s1"] = "l"}, ls(dir))
-- It is a dead symlink, but that's OK
stat_type, stat_perm = stat(dir .. "/s1", true)
stat_type, stat_perm = lstat(dir .. "/s1")
assert_equal("l", stat_type)
assert_equal("rwxrwxrwx", stat_perm)
-- Create a file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment