2013-10-14 5 views
3

나는 루아 키트에서 SIGINT를 잡으려고합니다. 궁극적으로 저는 SIGUSR1을 포착 할 수 있기를 원합니다. SIGUSR1의 수신시 로그 파일이 닫히고 다시 열리는 logrotate 호환 가능한 로깅을 작성할 수 있도록하려는 것입니다.리눅스에서 루아제의 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)"는 어느 쪽이라도 부르지 않는다. 루아 통역자의 C 측에서 이미 SIGINT를 잡는 것 같아요.

그래서 궁극적으로 SIGINT를 SIGUSR1로 변경하기로 결정했습니다. 나는 캡처를 트리거 것을 알 수 있지만, 나는 거기에 내 콜백 함수의 형식에 문제가 있지만 나는 그것을 해결하는 방법을 잘 모르겠어요처럼 소리

"PANIC: unprotected error in call to Lua API (bad callback)" 

를 얻을. 루아는 여전히 나에게 아주 새로운 것이다.

+0

핸들러 선언 전에 jit.off (핸들러)가 작동하는 것처럼 보입니다. 이것이 옳은 일입니까? – Matt

+0

C.signal (...) 호출에서 ffi.cast ("sighandler_t", handler)를 넣지 않으면 프로그램이 종료 될 때 충돌이 발생하지만 – Matt

+0

메모리에서 핸들러 함수에 대한 jit를 비활성화하여 작동하게했습니다. – Matt

답변

8

NOT VM이 이미 코드를 실행중인 경우 신호 처리기에서 LuaJIT VM을 호출해도 안전합니다. 루아 코드가 해석되거나 컴파일되는지 여부는 중요하지 않습니다. 신호 핸들러는 비동기 적으로 호출되며 VM은 일관된 상태가 아닐 수 있습니다.

두 번째 VM (ffi.C.luaL_newstate())을 생성하고 신호 처리기를 해당 VM의 기능으로 설정 한 다음 두 VM간에 어떻게 든 통신 할 수 있습니다. 그러나 그것은 매우 복잡하고 옳다는 것은 어렵습니다.

sigpending() (주기적으로 로그 기능에서 확인) 또는 signalfd() (이미 이벤트 처리 루프가있는 경우)을 사용하는 것이 더 쉽습니다.