aboutsummaryrefslogtreecommitdiffstats
path: root/util-src
diff options
context:
space:
mode:
Diffstat (limited to 'util-src')
-rw-r--r--util-src/signal.c81
1 files changed, 73 insertions, 8 deletions
diff --git a/util-src/signal.c b/util-src/signal.c
index 76d25d6f..0e5c66ca 100644
--- a/util-src/signal.c
+++ b/util-src/signal.c
@@ -32,8 +32,8 @@
#include <signal.h>
#include <stdlib.h>
-#ifdef __linux__
#include <unistd.h>
+#ifdef __linux__
#include <sys/signalfd.h>
#endif
@@ -372,18 +372,35 @@ static int l_kill(lua_State *L) {
#endif
-#ifdef __linux__
struct lsignalfd {
int fd;
sigset_t mask;
+#ifndef __linux__
+ int write_fd;
+#endif
};
+#ifndef __linux__
+#define MAX_SIGNALFD 32
+struct lsignalfd signalfds[MAX_SIGNALFD];
+static int signalfd_num = 0;
+static void signal2fd(int sig) {
+ for(int i = 0; i < signalfd_num; i++) {
+ if(sigismember(&signalfds[i].mask, sig)) {
+ write(signalfds[i].write_fd, &sig, sizeof(sig));
+ }
+ }
+}
+#endif
+
static int l_signalfd(lua_State *L) {
struct lsignalfd *sfd = lua_newuserdata(L, sizeof(struct lsignalfd));
+ int sig = luaL_checkinteger(L, 1);
sigemptyset(&sfd->mask);
- sigaddset(&sfd->mask, luaL_checkinteger(L, 1));
+ sigaddset(&sfd->mask, sig);
+#ifdef __linux__
if (sigprocmask(SIG_BLOCK, &sfd->mask, NULL) != 0) {
lua_pushnil(L);
return 1;
@@ -396,6 +413,30 @@ static int l_signalfd(lua_State *L) {
return 1;
}
+#else
+
+ if(signalfd_num >= MAX_SIGNALFD) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if(signal(sig, signal2fd) == SIG_ERR) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ int pipefd[2];
+
+ if(pipe(pipefd) == -1) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ sfd->fd = pipefd[0];
+ sfd->write_fd = pipefd[1];
+ signalfds[signalfd_num++] = *sfd;
+#endif
+
luaL_setmetatable(L, "signalfd");
return 1;
}
@@ -414,14 +455,28 @@ static int l_signalfd_getfd(lua_State *L) {
static int l_signalfd_read(lua_State *L) {
struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd");
+#ifdef __linux__
struct signalfd_siginfo siginfo;
if(read(sfd->fd, &siginfo, sizeof(siginfo)) < 0) {
return 0;
}
+
lua_pushinteger(L, siginfo.ssi_signo);
return 1;
+
+#else
+ int signo;
+
+ if(read(sfd->fd, &signo, sizeof(int)) < 0) {
+ return 0;
+ }
+
+ lua_pushinteger(L, signo);
+ return 1;
+#endif
+
}
static int l_signalfd_close(lua_State *L) {
@@ -432,11 +487,25 @@ static int l_signalfd_close(lua_State *L) {
return 1;
}
+#ifndef __linux__
+
+ if(close(sfd->write_fd) != 0) {
+ lua_pushboolean(L, 0);
+ return 1;
+ }
+
+ for(int i = signalfd_num; i > 0; i--) {
+ if(signalfds[i].fd == sfd->fd) {
+ signalfds[i] = signalfds[signalfd_num--];
+ }
+ }
+
+#endif
+
sfd->fd = -1;
lua_pushboolean(L, 1);
return 1;
}
-#endif
static const struct luaL_Reg lsignal_lib[] = {
{"signal", l_signal},
@@ -444,9 +513,7 @@ static const struct luaL_Reg lsignal_lib[] = {
#if defined(__unix__) || defined(__APPLE__)
{"kill", l_kill},
#endif
-#ifdef __linux__
{"signalfd", l_signalfd},
-#endif
{NULL, NULL}
};
@@ -454,7 +521,6 @@ int luaopen_prosody_util_signal(lua_State *L) {
luaL_checkversion(L);
int i = 0;
-#ifdef __linux__
luaL_newmetatable(L, "signalfd");
lua_pushcfunction(L, l_signalfd_close);
lua_setfield(L, -2, "__gc");
@@ -469,7 +535,6 @@ int luaopen_prosody_util_signal(lua_State *L) {
}
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
-#endif
/* add the library */
lua_newtable(L);