我想在luajit中捕获SIGINT.最终我希望能够捕获SIGUSR1.目的是允许我编写logrotate compatable日志记录,在收到SIGUSR1时,日志文件被关闭然后重新打开.
我怎么能用FFI做到这一点?
这是我到目前为止所拥有的.
local ffi = require("ffi")
local C = ffi.C
local SIG_ERR = -1
local SIGINT = 1
local SIGUSR1 = 10
ffi.cdef[[
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
]]
local function handler(signo)
print("caught sig\n")
end
if C.signal(SIGINT, handler) == SIG_ERR then
print("Can't catch SIGINT\n")
end
while 1 do
end
实际上,我认为这里有几件事情.我注意到你必须按两次ctrl c并退出程序.并且“抓住了sig”并没有被称为时间.我认为lua解释器的C端已经捕获了SIGINT.
所以我决定将SIGINT更改为SIGUSR1,因为这最终是我需要的.我注意到它触发了捕获,但我得到了
"PANIC: unprotected error in call to Lua API (bad callback)"
听起来我的回调函数的格式有问题,但我不知道如何纠正它. Lua对我来说仍然是一个新鲜事物.
解决方法:
如果VM已经在主动运行代码,则从信号处理程序调用LuaJIT VM是不安全的. Lua代码是否被解释或编译并不重要.信号处理程序是异步调用的,VM可能不是一致的状态.
您可以创建第二个VM(ffi.C.luaL_newstate()),为该VM中的函数设置信号处理程序,然后以某种方式在两个VM之间进行通信.但这很复杂,很难做到.
我想使用sigpending()(定期检查,例如在日志函数中)或signalfd()(如果你已经有一个事件处理循环)会更容易.