# HG changeset patch # User Kim Alvefur # Date 1708732844 -3600 # Node ID 6d96b6eeee5acad1256992ccf4dd97a7d86fda32 # Parent b27de3d2bad61f1d21e30458f20f5cc1680bdea2 util.signal: Wrap signalfd in an userdatum for gc handling etc diff -r b27de3d2bad6 -r 6d96b6eeee5a net/server_epoll.lua --- a/net/server_epoll.lua Sat Feb 24 00:20:35 2024 +0100 +++ b/net/server_epoll.lua Sat Feb 24 01:00:44 2024 +0100 @@ -1147,12 +1147,13 @@ local hook_signal; if have_signal and signal.signalfd then local function dispatch(self) - return self:on("signal", signal.signalfd_read(self:getfd())); + return self:on("signal", self.conn:read()); end function hook_signal(signum, cb) local watch = watchfd(signal.signalfd(signum), dispatch); watch.listeners = { onsignal = cb }; + watch.close = nil; -- revert to default return watch; end end diff -r b27de3d2bad6 -r 6d96b6eeee5a util-src/signal.c --- a/util-src/signal.c Sat Feb 24 00:20:35 2024 +0100 +++ b/util-src/signal.c Sat Feb 24 01:00:44 2024 +0100 @@ -373,29 +373,66 @@ #endif #ifdef __linux__ +struct lsignalfd { + int fd; + sigset_t mask; +}; + static int l_signalfd(lua_State *L) { - sigset_t mask; + struct lsignalfd *sfd = lua_newuserdata(L, sizeof(struct lsignalfd)); + + sigemptyset(&sfd->mask); + sigaddset(&sfd->mask, luaL_checkinteger(L, 1)); + + sigprocmask(SIG_BLOCK, &sfd->mask, NULL); /* TODO check err */ + + sfd->fd = signalfd(-1, &sfd->mask, SFD_NONBLOCK); - sigemptyset(&mask); - sigaddset(&mask, luaL_checkinteger(L, 1)); + if(sfd->fd == -1) { + lua_pushnil(L); + return 1; + } + + luaL_setmetatable(L, "signalfd"); + return 1; +} - sigprocmask(SIG_BLOCK, &mask, NULL); /* TODO check err */ +static int l_signalfd_getfd(lua_State *L) { + struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); - lua_pushinteger(L, signalfd(-1, &mask, SFD_NONBLOCK)); + if (sfd->fd == -1) { + lua_pushnil(L); + return 1; + } + + lua_pushinteger(L, sfd->fd); return 1; } static int l_signalfd_read(lua_State *L) { - const int sigfd = luaL_checkinteger(L, 1); + struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); struct signalfd_siginfo siginfo; - if(read(sigfd, &siginfo, sizeof(siginfo)) < 0) { + 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[] = { @@ -406,7 +443,6 @@ #endif #ifdef __linux__ {"signalfd", l_signalfd}, - {"signalfd_read", l_signalfd_read}, #endif {NULL, NULL} }; @@ -415,6 +451,23 @@ luaL_checkversion(L); 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);