#include <string.h>
#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>
/* struct net_device_stats is buggy on amd64, redefine it */
}
/**
- * getnameinfo(address, family)
+ * getnameinfo(address, family[, timeout])
*/
static int nixio_getnameinfo(lua_State *L) {
const char *ip = luaL_checkstring(L, 1);
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];
struct sockaddr_storage saddr;
int res = getnameinfo((struct sockaddr *)&saddr, sizeof(saddr),
host, sizeof(host), NULL, 0, NI_NAMEREQD);
+
+#ifdef __linux__
+ if (timeout > 0 && timeout < 1000)
+ {
+ ualarm(0, 0);
+ sigaction(SIGALRM, &sa_old, NULL);
+ }
+#endif
+
if (res) {
lua_pushnil(L);
lua_pushinteger(L, res);
}
#endif
-/**
- * protoent conversion helper
- */
-static int nixio__pushprotoent(lua_State *L, struct protoent *e) {
- int i;
- if (e) {
- lua_newtable(L);
-
- lua_pushstring(L, e->p_name);
- lua_setfield(L, -2, "name");
-
- lua_pushnumber(L, e->p_proto);
- lua_setfield(L, -2, "proto");
-
- lua_newtable(L);
- for (i = 0; e->p_aliases[i]; i++) {
- lua_pushstring(L, e->p_aliases[i]);
- lua_rawseti(L, -2, i+1);
- }
- lua_setfield(L, -2, "aliases");
- return 1;
- } else {
- return 0;
- }
-}
-
-/**
- * getprotobyname(name)
- */
-static int nixio_getprotobyname(lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- struct protoent *res = getprotobyname(name);
- return nixio__pushprotoent(L, res);
-}
-
-/**
- * getprotobynumber(proto)
- */
-static int nixio_getprotobynumber(lua_State *L) {
- int proto = luaL_checkinteger(L, 1);
- struct protoent *res = getprotobynumber(proto);
- return nixio__pushprotoent(L, res);
-}
/* module table */
static const luaL_reg R[] = {
#if defined(__linux__) || defined(BSD)
- {"getifaddrs", nixio_getifaddrs},
+ {"getifaddrs", nixio_getifaddrs},
#endif
- {"getaddrinfo", nixio_getaddrinfo},
- {"getnameinfo", nixio_getnameinfo},
- {"getprotobyname", nixio_getprotobyname},
- {"getprotobynumber", nixio_getprotobynumber},
- {NULL, NULL}
+ {"getaddrinfo", nixio_getaddrinfo},
+ {"getnameinfo", nixio_getnameinfo},
+ {NULL, NULL}
};
/* object table */
static const luaL_reg M[] = {
- {"getsockname", nixio_sock_getsockname},
- {"getpeername", nixio_sock_getpeername},
- {NULL, NULL}
+ {"getsockname", nixio_sock_getsockname},
+ {"getpeername", nixio_sock_getpeername},
+ {NULL, NULL}
};
void nixio_open_address(lua_State *L) {