# HG changeset patch # User jbe # Date 1428598793 -7200 # Node ID e99265c3372deb787b7a37c44514860e50a36a2e # Parent bff286e7496e0cc22178f89dcfdf912a3e017db2 New function moonbridge_io.locallisten(path) to listen on local (unix domain) sockets diff -r bff286e7496e -r e99265c3372d moonbridge_io.c --- a/moonbridge_io.c Thu Apr 09 18:49:37 2015 +0200 +++ b/moonbridge_io.c Thu Apr 09 18:59:53 2015 +0200 @@ -747,6 +747,49 @@ return moonbr_io_tcpconnect_impl(L, 1); } +static int moonbr_io_locallisten(lua_State *L) { + moonbr_io_listener_t *listener; + 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); + listener = lua_newuserdata(L, sizeof(moonbr_io_listener_t)); + luaL_setmetatable(L, MOONBR_IO_LISTENER_MT_REGKEY); + sock = socket( + PF_LOCAL, + SOCK_STREAM | SOCK_CLOEXEC, + 0 + ); + if (sock < 0) { + moonbr_io_errmsg(); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + if (bind(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) { + moonbr_io_errmsg(); + close(sock); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + if (listen(sock, MOONBR_IO_LISTEN_BACKLOG)) { + moonbr_io_errmsg(); + close(sock); + lua_pushnil(L); + lua_pushstring(L, errmsg); + return 2; + } + listener->fd = sock; + listener->nonblocking = -1; + return 1; +} + static int moonbr_io_tcplisten(lua_State *L) { moonbr_io_listener_t *listener; const char *host, *port; @@ -1021,6 +1064,7 @@ {"localconnect_nb", moonbr_io_localconnect_nb}, {"tcpconnect", moonbr_io_tcpconnect}, {"tcpconnect_nb", moonbr_io_tcpconnect_nb}, + {"locallisten", moonbr_io_locallisten}, {"tcplisten", moonbr_io_tcplisten}, {"poll", moonbr_io_poll}, {NULL, NULL}