Nginx 如何使用ffi.C.lstat?

Nginx 如何使用ffi.C.lstat?,nginx,lua,ffi,Nginx,Lua,Ffi,我想通过我的ngx_lua程序中的lstat函数获取文件的基本信息。init.lua的内容作为休耕: local ffi = require "ffi" local ffi_C = ffi.C local ffi_new = ffi.new ffi.cdef[[ typedef long long time_t; typedef struct timespec { time_t tv_sec; long tv_nsec;

我想通过我的ngx_lua程序中的lstat函数获取文件的基本信息。init.lua的内容作为休耕:

local ffi = require "ffi"
local ffi_C = ffi.C
local ffi_new = ffi.new

ffi.cdef[[
    typedef long long time_t;
    typedef struct timespec {
        time_t  tv_sec;
        long    tv_nsec;
        ...;
    };
    typedef struct stat {
        struct timespec st_mtim;
        ...;
    };

    int lstat(const char *path, struct stat *buf);
]]

buf = ffi_new("struct stat *")

function checkfile (filename, buf)
    ffi_C.lstat(filename, buf)
end
当我启动nginx时,出现了一些错误。内容为休耕:

local ffi = require "ffi"
local ffi_C = ffi.C
local ffi_new = ffi.new

ffi.cdef[[
    typedef long long time_t;
    typedef struct timespec {
        time_t  tv_sec;
        long    tv_nsec;
        ...;
    };
    typedef struct stat {
        struct timespec st_mtim;
        ...;
    };

    int lstat(const char *path, struct stat *buf);
]]

buf = ffi_new("struct stat *")

function checkfile (filename, buf)
    ffi_C.lstat(filename, buf)
end
  • 2014/04/25 15:00:39[错误]26396#0:lua入口线程中止: 运行时错误:/home/nginx/conf/cop/init.lua:42: /usr/local/lib/libluajit-5.1.so.2:未定义的符号:lstat 堆栈回溯: 协同程序0: [C] :在函数“索引”中 /home/nginx/conf/cop/init.lua:42:在函数“checkfile”中 /home/nginx/conf/cop/check1.lua:37:in函数,context:ngx.timer
buf=ffi_new(“struct stat*”)
创建指向
struct stat
对象的新指针;它不分配实际的
struct stat
实例。您需要的是
ffi\u new(“struct stat”)

在尝试使用FFI之前,请确保您熟悉C的内存模型,因为使用LuaJIT的FFI基本上是用C编写的。它不会保护您不去引用
NULL
,等等


而且,
buf
是一个全局变量,您可能不需要它。确保它是本地的

除了上述类型的问题外,还有一个更为繁琐的问题: 对于glibc,stat()和friends(lstat(),fstat(),…)通常是解析为uxstat()等的宏

__xstat()接受3个参数,第一个参数指定要将哪个版本的struct stat用作缓冲区,但布局似乎非常依赖于libc版本

(如中所述)

为了解决luaJIT的FFI的这个问题,似乎最可靠的方法是使用stat的编号(即在arm32和x86_64上为106)发出syscall(),并从内核中获取struct stat定义(在x86和arm32上相同,在x86_64上不同)


您还可以使用ljsyscall(),我没有尝试过。

首先,感谢您的帮助!但是,当我启动nginx.libluajit.so时,同样的错误也发生了。因此,我无法知道lstat符号。