371 } |
371 } |
372 |
372 |
373 #endif |
373 #endif |
374 |
374 |
375 #ifdef __linux__ |
375 #ifdef __linux__ |
|
376 struct lsignalfd { |
|
377 int fd; |
|
378 sigset_t mask; |
|
379 }; |
|
380 |
376 static int l_signalfd(lua_State *L) { |
381 static int l_signalfd(lua_State *L) { |
377 sigset_t mask; |
382 struct lsignalfd *sfd = lua_newuserdata(L, sizeof(struct lsignalfd)); |
378 |
383 |
379 sigemptyset(&mask); |
384 sigemptyset(&sfd->mask); |
380 sigaddset(&mask, luaL_checkinteger(L, 1)); |
385 sigaddset(&sfd->mask, luaL_checkinteger(L, 1)); |
381 |
386 |
382 sigprocmask(SIG_BLOCK, &mask, NULL); /* TODO check err */ |
387 sigprocmask(SIG_BLOCK, &sfd->mask, NULL); /* TODO check err */ |
383 |
388 |
384 lua_pushinteger(L, signalfd(-1, &mask, SFD_NONBLOCK)); |
389 sfd->fd = signalfd(-1, &sfd->mask, SFD_NONBLOCK); |
|
390 |
|
391 if(sfd->fd == -1) { |
|
392 lua_pushnil(L); |
|
393 return 1; |
|
394 } |
|
395 |
|
396 luaL_setmetatable(L, "signalfd"); |
|
397 return 1; |
|
398 } |
|
399 |
|
400 static int l_signalfd_getfd(lua_State *L) { |
|
401 struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); |
|
402 |
|
403 if (sfd->fd == -1) { |
|
404 lua_pushnil(L); |
|
405 return 1; |
|
406 } |
|
407 |
|
408 lua_pushinteger(L, sfd->fd); |
385 return 1; |
409 return 1; |
386 } |
410 } |
387 |
411 |
388 static int l_signalfd_read(lua_State *L) { |
412 static int l_signalfd_read(lua_State *L) { |
389 const int sigfd = luaL_checkinteger(L, 1); |
413 struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); |
390 struct signalfd_siginfo siginfo; |
414 struct signalfd_siginfo siginfo; |
391 |
415 |
392 if(read(sigfd, &siginfo, sizeof(siginfo)) < 0) { |
416 if(read(sfd->fd, &siginfo, sizeof(siginfo)) < 0) { |
393 return 0; |
417 return 0; |
394 } |
418 } |
395 |
419 |
396 lua_pushinteger(L, siginfo.ssi_signo); |
420 lua_pushinteger(L, siginfo.ssi_signo); |
|
421 return 1; |
|
422 } |
|
423 |
|
424 static int l_signalfd_close(lua_State *L) { |
|
425 struct lsignalfd *sfd = luaL_checkudata(L, 1, "signalfd"); |
|
426 |
|
427 if(close(sfd->fd) != 0) { |
|
428 lua_pushboolean(L, 0); |
|
429 return 1; |
|
430 } |
|
431 |
|
432 sfd->fd = -1; |
|
433 lua_pushboolean(L, 1); |
397 return 1; |
434 return 1; |
398 } |
435 } |
399 #endif |
436 #endif |
400 |
437 |
401 static const struct luaL_Reg lsignal_lib[] = { |
438 static const struct luaL_Reg lsignal_lib[] = { |
404 #if defined(__unix__) || defined(__APPLE__) |
441 #if defined(__unix__) || defined(__APPLE__) |
405 {"kill", l_kill}, |
442 {"kill", l_kill}, |
406 #endif |
443 #endif |
407 #ifdef __linux__ |
444 #ifdef __linux__ |
408 {"signalfd", l_signalfd}, |
445 {"signalfd", l_signalfd}, |
409 {"signalfd_read", l_signalfd_read}, |
|
410 #endif |
446 #endif |
411 {NULL, NULL} |
447 {NULL, NULL} |
412 }; |
448 }; |
413 |
449 |
414 int luaopen_prosody_util_signal(lua_State *L) { |
450 int luaopen_prosody_util_signal(lua_State *L) { |
415 luaL_checkversion(L); |
451 luaL_checkversion(L); |
416 int i = 0; |
452 int i = 0; |
|
453 |
|
454 #ifdef __linux__ |
|
455 luaL_newmetatable(L, "signalfd"); |
|
456 lua_pushcfunction(L, l_signalfd_close); |
|
457 lua_setfield(L, -2, "__gc"); |
|
458 lua_createtable(L, 0, 1); |
|
459 { |
|
460 lua_pushcfunction(L, l_signalfd_getfd); |
|
461 lua_setfield(L, -2, "getfd"); |
|
462 lua_pushcfunction(L, l_signalfd_read); |
|
463 lua_setfield(L, -2, "read"); |
|
464 lua_pushcfunction(L, l_signalfd_close); |
|
465 lua_setfield(L, -2, "close"); |
|
466 } |
|
467 lua_setfield(L, -2, "__index"); |
|
468 lua_pop(L, 1); |
|
469 #endif |
417 |
470 |
418 /* add the library */ |
471 /* add the library */ |
419 lua_newtable(L); |
472 lua_newtable(L); |
420 luaL_setfuncs(L, lsignal_lib, 0); |
473 luaL_setfuncs(L, lsignal_lib, 0); |
421 |
474 |