diff options
Diffstat (limited to 'util-src/signal.c')
-rw-r--r-- | util-src/signal.c | 100 |
1 files changed, 94 insertions, 6 deletions
diff --git a/util-src/signal.c b/util-src/signal.c index 1a398fa0..76d25d6f 100644 --- a/util-src/signal.c +++ b/util-src/signal.c @@ -32,13 +32,14 @@ #include <signal.h> #include <stdlib.h> +#ifdef __linux__ +#include <unistd.h> +#include <sys/signalfd.h> +#endif #include "lua.h" #include "lauxlib.h" -#if (LUA_VERSION_NUM == 501) -#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) -#endif #if (LUA_VERSION_NUM < 503) #define lua_isinteger(L, n) lua_isnumber(L, n) #endif @@ -371,21 +372,105 @@ static int l_kill(lua_State *L) { #endif +#ifdef __linux__ +struct lsignalfd { + int fd; + sigset_t mask; +}; + +static int l_signalfd(lua_State *L) { + struct lsignalfd *sfd = lua_newuserdata(L, sizeof(struct lsignalfd)); + + sigemptyset(&sfd->mask); + sigaddset(&sfd->mask, luaL_checkinteger(L, 1)); + + if (sigprocmask(SIG_BLOCK, &sfd->mask, NULL) != 0) { + lua_pushnil(L); + return 1; + }; + + sfd->fd = signalfd(-1, &sfd->mask, SFD_NONBLOCK); + + if(sfd->fd == -1) { + lua_pushnil(L); + return 1; + } + + luaL_setmetatable(L, "signalfd"); + return 1; +} + +static int l_signalfd_getfd(lua_State *L) { + struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); + + if (sfd->fd == -1) { + lua_pushnil(L); + return 1; + } + + lua_pushinteger(L, sfd->fd); + return 1; +} + +static int l_signalfd_read(lua_State *L) { + struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); + struct signalfd_siginfo siginfo; + + if(read(sfd->fd, &siginfo, sizeof(siginfo)) < 0) { + return 0; + } + + lua_pushinteger(L, siginfo.ssi_signo); + return 1; +} + +static int l_signalfd_close(lua_State *L) { + struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); + + if(close(sfd->fd) != 0) { + lua_pushboolean(L, 0); + return 1; + } + + sfd->fd = -1; + lua_pushboolean(L, 1); + return 1; +} +#endif + static const struct luaL_Reg lsignal_lib[] = { {"signal", l_signal}, {"raise", l_raise}, #if defined(__unix__) || defined(__APPLE__) {"kill", l_kill}, #endif +#ifdef __linux__ + {"signalfd", l_signalfd}, +#endif {NULL, NULL} }; -int luaopen_util_signal(lua_State *L) { -#if (LUA_VERSION_NUM > 501) +int luaopen_prosody_util_signal(lua_State *L) { luaL_checkversion(L); -#endif int i = 0; +#ifdef __linux__ + luaL_newmetatable(L, "signalfd"); + lua_pushcfunction(L, l_signalfd_close); + lua_setfield(L, -2, "__gc"); + lua_createtable(L, 0, 1); + { + lua_pushcfunction(L, l_signalfd_getfd); + lua_setfield(L, -2, "getfd"); + lua_pushcfunction(L, l_signalfd_read); + lua_setfield(L, -2, "read"); + lua_pushcfunction(L, l_signalfd_close); + lua_setfield(L, -2, "close"); + } + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); +#endif + /* add the library */ lua_newtable(L); luaL_setfuncs(L, lsignal_lib, 0); @@ -413,3 +498,6 @@ int luaopen_util_signal(lua_State *L) { return 1; } +int luaopen_util_signal(lua_State *L) { + return luaopen_prosody_util_signal(L); +} |