libs/nixio: implement optional timeout for getnameinfo() on Linux
This commit is contained in:
parent
d135599c51
commit
c755e818c4
1 changed files with 43 additions and 1 deletions
|
@ -23,6 +23,15 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* setjmp() / longjmp() stuff */
|
||||||
|
static jmp_buf nixio__jump_alarm;
|
||||||
|
static void nixio__handle_alarm(int sig) { longjmp(nixio__jump_alarm, 1); }
|
||||||
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
/* struct net_device_stats is buggy on amd64, redefine it */
|
/* struct net_device_stats is buggy on amd64, redefine it */
|
||||||
|
@ -271,11 +280,38 @@ static int nixio_getaddrinfo(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getnameinfo(address, family)
|
* getnameinfo(address, family[, timeout])
|
||||||
*/
|
*/
|
||||||
static int nixio_getnameinfo(lua_State *L) {
|
static int nixio_getnameinfo(lua_State *L) {
|
||||||
const char *ip = luaL_checkstring(L, 1);
|
const char *ip = luaL_checkstring(L, 1);
|
||||||
const char *family = luaL_optstring(L, 2, NULL);
|
const char *family = luaL_optstring(L, 2, NULL);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
struct sigaction sa_new, sa_old;
|
||||||
|
int timeout = luaL_optnumber(L, 3, 0);
|
||||||
|
if (timeout > 0 && timeout < 1000)
|
||||||
|
{
|
||||||
|
sa_new.sa_handler = nixio__handle_alarm;
|
||||||
|
sa_new.sa_flags = 0;
|
||||||
|
sigemptyset(&sa_new.sa_mask);
|
||||||
|
sigaction(SIGALRM, &sa_new, &sa_old);
|
||||||
|
|
||||||
|
/* user timeout exceeded */
|
||||||
|
if (setjmp(nixio__jump_alarm))
|
||||||
|
{
|
||||||
|
sigaction(SIGALRM, &sa_old, NULL);
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushinteger(L, EAI_AGAIN);
|
||||||
|
lua_pushstring(L, gai_strerror(EAI_AGAIN));
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ualarm(timeout * 1000, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
char host[NI_MAXHOST];
|
char host[NI_MAXHOST];
|
||||||
|
|
||||||
struct sockaddr_storage saddr;
|
struct sockaddr_storage saddr;
|
||||||
|
@ -297,6 +333,12 @@ static int nixio_getnameinfo(lua_State *L) {
|
||||||
|
|
||||||
int res = getnameinfo((struct sockaddr *)&saddr, sizeof(saddr),
|
int res = getnameinfo((struct sockaddr *)&saddr, sizeof(saddr),
|
||||||
host, sizeof(host), NULL, 0, NI_NAMEREQD);
|
host, sizeof(host), NULL, 0, NI_NAMEREQD);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
if (timeout > 0 && timeout < 1000)
|
||||||
|
sigaction(SIGALRM, &sa_old, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
lua_pushinteger(L, res);
|
lua_pushinteger(L, res);
|
||||||
|
|
Loading…
Reference in a new issue