aboutsummaryrefslogtreecommitdiffstats
path: root/util-src/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-src/signal.c')
-rw-r--r--util-src/signal.c100
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);
+}