lib c stat и функция LuaJIT - PullRequest
0 голосов
/ 11 февраля 2020

Я весь день ковыряюсь в одном загадочном поведении LuaJIT. Функция libc stat возвращает неправильное значение в своем буфере stat.

Сценарий LuaJIT:

-- definitions for sys/types.h
 typedef uint32_t      mode_t;
 typedef uint64_t      dev_t;
 typedef uint64_t      ino_t;
 typedef unsigned int  nlink_t;
 typedef int           pid_t;
 typedef unsigned int  id_t;
 typedef unsigned int  uid_t;
 typedef unsigned int  gid_t;
 typedef int64_t       off_t;
 typedef long          blksize_t;
 typedef int64_t       blkcnt_t;
 typedef uint64_t      fsblkcnt_t;
 typedef uint64_t      fsfilcnt_t;

-- for sys/stat.h
  struct stat {
   dev_t      st_dev;         /* Device */
   ino_t      st_ino; /* File serial number. */
   nlink_t    st_nlink;     /* Link count.  */
   mode_t     st_mode; /* File mode.  */
   uid_t      st_uid; /* User ID of the file's owner. */
   gid_t      st_gid; /* Group ID of the file's group.*/
   int        __pad0;
   dev_t      st_rdev; /* Device number, if device.  */
   off_t      st_size;     /* Size of file, in bytes.  */
   blksize_t  st_blksize; /* Optimal block size for I/O.  */
   blkcnt_t   st_blocks; /* Number 512-byte blocks allocated. */
   /* __USE_XOPEN2K8 */
   struct timespec st_atim; /* Time of last access.  */
   struct timespec st_mtim; /* Time of last modification.  */
   struct timespec st_ctim; /* Time of last status change.  */
   long   __unused[3];
  };
  /* luajit calls this */
  int __xstat(int ver, const char *path, struct stat *buf); 

-- lua stat function part
stat = function(path, buf) return ffi.C.__xstat(_STAT_VER, path, buf) end;

Выше были взяты из заголовочных файлов моей системы C. Теперь вызов LuaJIT:

local buf = ffi.new("struct stat[1]")
local res = stat('main.c', buf)
ffi.cdef [[
 int printf(const char *fmt, ...);
]]
ffi.C.printf("size: %lu, ino: %lu, mode: %d\n", buf[0].st_size, buf[0].st_ino, buf[0].st_mode);

struct stat[1] в ffi.new любезно предложен списком рассылки luajit.

Обновление

Идея состоит в том, чтобы позвонить linux __xtat. Декларация добавлена.

Подход __xstat был взят из https://github.com/Wiladams/LJIT2libc. Иначе для меня слишком много определений в заголовках C.

Вывод идет нормально, до поля st_mode. Поле ноль. Я сделал тест с языком C и все прошло хорошо. Так что проблема в том, что LuaJIT stat дает мне неправильные результаты. Посоветуйте пожалуйста что делать. Положите весь день на эту штуку.

1 Ответ

0 голосов
/ 12 февраля 2020

Я сделал несколько опечаток в моих ffi.cdef объявлениях типов. Теперь проблема решена с помощью списка пользователей luajit. Чтобы сделать быстрое резюме:

  1. Возьмите вывод команды clang -E <some_c_file>.c, которая вызывается из C исходного файла, который содержит #include <sys/stat.h>.
  2. . 1011 * определение.
  3. Моя системная функция stat имеет слишком много уровней макро-мусора. В конце концов, функция stat вызывает __xstat. Единственный разумный способ вызвать функцию stat - это сделать syscall.
  4. . Помните, что функция Lua print не знает о типе cdata. И printf не знает о Lua типах. Но у luajit есть хорошее и простое объяснение того, как преобразовывать общие типы данных туда и обратно.
...