# HG changeset patch # User jbe # Date 1428598177 -7200 # Node ID bff286e7496e0cc22178f89dcfdf912a3e017db2 # Parent 0daa33d9a1471f940ea40d9622d03fe6fe8677c0 Added function moonbridge_io.localconnect(pathname) to connect to local (unix domain) socket diff -r 0daa33d9a147 -r bff286e7496e moonbridge_io.c --- a/moonbridge_io.c Thu Apr 09 18:46:06 2015 +0200 +++ b/moonbridge_io.c Thu Apr 09 18:49:37 2015 +0200 @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -625,6 +626,53 @@ return 0; } +static int moonbr_io_localconnect_impl(lua_State *L, int nonblocking) { + const char *path; + struct sockaddr_un sockaddr = { .sun_family = AF_LOCAL }; + const int path_maxlen = sizeof(struct sockaddr_un) - ( + (void *)sockaddr.sun_path - (void *)&sockaddr + ) - 1; /* one byte for termination */ + int sock; + path = luaL_checkstring(L, 1); + if (strlen(path) > path_maxlen) luaL_error(L, "Path too long; only %i characters allowed", path_maxlen); + strcpy(sockaddr.sun_path, path); + sock = socket( + PF_LOCAL, + SOCK_STREAM | SOCK_CLOEXEC | (nonblocking ? SOCK_NONBLOCK : 0), + 0 + ); + if (sock < 0) { + moonbr_io_errmsg(); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) { + if (!nonblocking && errno == EINTR) { + moonbr_io_errmsg(); + close(sock); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) { + moonbr_io_errmsg(); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + } + moonbr_io_pushhandle(L, sock); + return 1; +} + +static int moonbr_io_localconnect(lua_State *L) { + return moonbr_io_localconnect_impl(L, 0); +} + +static int moonbr_io_localconnect_nb(lua_State *L) { + return moonbr_io_localconnect_impl(L, 1); +} + static int moonbr_io_tcpconnect_impl(lua_State *L, int nonblocking) { const char *host, *port; struct addrinfo hints = { 0, }; @@ -969,6 +1017,8 @@ }; static const struct luaL_Reg moonbr_io_module_funcs[] = { + {"localconnect", moonbr_io_localconnect}, + {"localconnect_nb", moonbr_io_localconnect_nb}, {"tcpconnect", moonbr_io_tcpconnect}, {"tcpconnect_nb", moonbr_io_tcpconnect_nb}, {"tcplisten", moonbr_io_tcplisten},