0

I want to get the file's basic infomation with the lstat function by in my ngx_lua programme. The init.lua's content as fallow:

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

When I start my nginx, there are some errors happen. The content as fallow:

  • 2014/04/25 15:00:39 [error] 26396#0: lua entry thread aborted: runtime error: /home/nginx/conf/cop/init.lua:42: /usr/local/lib/libluajit-5.1.so.2: undefined symbol: lstat stack traceback: coroutine 0: [C]: in function '__index' /home/nginx/conf/cop/init.lua:42: in function 'checkfile' /home/nginx/conf/cop/check1.lua:37: in function , context: ngx.timer
yakantosat
  • 11
  • 4

2 Answers2

1

apart from those type issues above, there is a much more tedious one: with glibc, stat() and friends (lstat(), fstat(), ...) are normally macros that resolve to __xstat() etc.

__xstat() takes 3 args, the first one specifying which version of the struct stat you would like as a buffer, but the layout seems very dependent on the libc version.

(this is for example mentioned in c and LD_PRELOAD. open and open64 calls intercepted, but not stat64)

to resolve this issue for luaJIT's FFI, it seemed the most reliable to issue syscall() with the number for stat (i. e. 106 on arm32 and x86_64) and take the struct stat definitions from the kernel (same on x86 and arm32, different on x86_64).

you could also potentially use ljsyscall (https://github.com/justincormack/ljsyscall) which i didn't try.

vlkr
  • 31
  • 1
0

buf = ffi_new("struct stat *") creates a new pointer to a struct stat object; it doesn't allocate an actual struct stat instance. You want ffi_new("struct stat") instead.

Before attempting to do anything with the FFI, be sure you are familiar with C's memory model, because using LuaJIT's FFI is basically writing in C. It won't protect you from dereferencing NULL, etc.

Also, buf is a global, which you probably don't want. Be sure to make it local.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • Fistly, thanks for your help! But,the same error happened when I started my nginx.The libluajit.so can not know the lstat symbol. – yakantosat Apr 28 '14 at 06:48