]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
fix map() command on 32-bit platforms; regressed in 5.2.0
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 13 Nov 2020 13:16:32 +0000 (14:16 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 16 Nov 2020 08:20:04 +0000 (09:20 +0100)
LuaJIT FFI was using opendir() (etc.) variants with 32-bit inodes
but the C parts was using them as 64-bit inode variants.
Consequently the `struct dirent` layout didn't match and we were getting
filenames shifted by eight bytes.

Now the whole dir-listing lua function is written in C.

.luacheckrc
NEWS
daemon/bindings/impl.c
daemon/lua/kluautil.lua

index 0cf0b884a49fa8fe5990dec06f37accf85101482..67bc18f6b1916c4155eec4b9d02680b2c686f0b5 100644 (file)
@@ -20,6 +20,7 @@ new_read_globals = {
        'user',
        'verbose',
        'worker',
+       'kluautil_list_dir',
        -- Sandbox declarations
        'kB',
        'MB',
diff --git a/NEWS b/NEWS
index 2eae308245ab8f0c403df6269eb4d9a77355c102..9d8cde991c91052e85da18049a56c82e44337824 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
 Knot Resolver X.Y.X (yyyy-mm-dd)
 ================================
 
+Bugfixes
+--------
+- fix map() command on 32-bit platforms; regressed in 5.2.0 (!1093)
+
 
 Knot Resolver 5.2.0 (2020-11-11)
 ================================
index d10f452573884c858e02d44810aff8940589be06..d9ad0774f45089c0baff87253fe02f9f0dd060b2 100644 (file)
@@ -2,6 +2,7 @@
  *  SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#include <dirent.h>
 #include <lua.h>
 #include <lauxlib.h>
 #include <string.h>
@@ -29,6 +30,29 @@ const char * lua_table_checkindices(lua_State *L, const char *keys[])
        return NULL;
 }
 
+/** Return table listing filenames in a given directory (ls -A). */
+static int kluautil_list_dir(lua_State *L)
+{
+       lua_newtable(L); // empty table even on errors
+
+       const char *path = lua_tolstring(L, 1, NULL);
+       if (!path) return 1;
+       DIR *dir = opendir(path);
+       if (!dir) return 1;
+
+       struct dirent *entry;
+       int lua_i = 1;
+       while ((entry = readdir(dir)) != NULL) {
+               if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) {
+                       lua_pushstring(L, entry->d_name);
+                       lua_rawseti(L, -2, lua_i++);
+               }
+       }
+
+       closedir(dir);
+       return 1;
+}
+
 
 /* Each of these just creates the correspondingly named lua table of functions. */
 int kr_bindings_cache   (lua_State *L); /* ./cache.c   */
@@ -44,6 +68,9 @@ void kr_bindings_register(lua_State *L)
        kr_bindings_modules(L);
        kr_bindings_net(L);
        kr_bindings_worker(L);
+
+       /* Finally some lua utils *written in C*, not really a binding. */
+       lua_register(L, "kluautil_list_dir", kluautil_list_dir);
 }
 
 void lua_error_p(lua_State *L, const char *fmt, ...)
index 57912e7ba10f03a2ac5f8ce9772e72c50a3c8d66..e73e952cfd8fe48dd3a412fda6fab98cea646bb5 100644 (file)
@@ -1,6 +1,5 @@
 -- SPDX-License-Identifier: GPL-3.0-or-later
 
-local ffi = require('ffi')
 local kluautil = {}
 
 -- Get length of table
@@ -28,14 +27,6 @@ function kluautil.kr_table_unpack(tab)
        return unpack(tab, 1, tab.n)
 end
 
-ffi.cdef([[
-       typedef struct __dirstream DIR;
-       DIR *opendir(const char *name);
-       struct dirent *readdir(DIR *dirp);
-       int closedir(DIR *dirp);
-       char *strerror(int errnum);
-]])
-
 -- Fetch over HTTPS
 function kluautil.kr_https_fetch(url, out_file, ca_file)
        local http_ok, http_request = pcall(require, 'http.request')
@@ -88,26 +79,6 @@ function kluautil.kr_https_fetch(url, out_file, ca_file)
        return true
 end
 
--- List directory
-function kluautil.list_dir (path)
-       local results = {}
-       local dir = ffi.C.opendir(path)
-       if dir == nil then
-               return results
-       end
-
-       local entry = ffi.C.readdir(dir)
-       while entry ~= nil do
-               local entry_name = ffi.string(ffi.C.kr_dirent_name(entry))
-               if entry_name ~= '.' and entry_name ~= '..' then
-                       table.insert(results, entry_name)
-               end
-               entry = ffi.C.readdir(dir)
-       end
-
-       ffi.C.closedir(dir)
-
-       return results
-end
+kluautil.list_dir = kluautil_list_dir
 
 return kluautil