# HG changeset patch # User jbe # Date 1428459723 -7200 # Node ID c9ffbdac1337d0648978c1760f6d56022a148327 # Parent acaa85256c4ba0cab4b38034a110b6147e01e63c New function moonbridge_io.tcpconnect_nb(...) for nonblocking connects diff -r acaa85256c4b -r c9ffbdac1337 moonbridge_io.c --- a/moonbridge_io.c Wed Apr 08 04:00:41 2015 +0200 +++ b/moonbridge_io.c Wed Apr 08 04:22:03 2015 +0200 @@ -484,7 +484,7 @@ return 0; } -int moonbr_io_tcpconnect(lua_State *L) { +static int moonbr_io_tcpconnect_impl(lua_State *L, int nonblocking) { const char *host, *port; struct addrinfo hints = { 0, }; struct addrinfo *res, *addrinfo; @@ -516,22 +516,42 @@ } addrinfo = res; moonbr_io_tcpconnect_found: - sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); + sock = socket( + addrinfo->ai_family, + addrinfo->ai_socktype | SOCK_CLOEXEC | (nonblocking ? SOCK_NONBLOCK : 0), + addrinfo->ai_protocol + ); if (sock < 0) { moonbr_io_errmsg(); lua_pushnil(L); lua_pushstring(L, errmsg); } if (connect(sock, addrinfo->ai_addr, addrinfo->ai_addrlen)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + 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, 1); return 1; } +static int moonbr_io_tcpconnect(lua_State *L) { + return moonbr_io_tcpconnect_impl(L, 0); +} + +static int moonbr_io_tcpconnect_nb(lua_State *L) { + return moonbr_io_tcpconnect_impl(L, 1); +} + static const struct luaL_Reg moonbr_io_handle_methods[] = { {"read", moonbr_io_read}, {"read_nb", moonbr_io_read_nb}, @@ -556,6 +576,7 @@ static const struct luaL_Reg moonbr_io_module_funcs[] = { {"tcpconnect", moonbr_io_tcpconnect}, + {"tcpconnect_nb", moonbr_io_tcpconnect_nb}, {NULL, NULL} }; diff -r acaa85256c4b -r c9ffbdac1337 moonbridge_io.h --- a/moonbridge_io.h Wed Apr 08 04:00:41 2015 +0200 +++ b/moonbridge_io.h Wed Apr 08 04:22:03 2015 +0200 @@ -2,5 +2,6 @@ void moonbr_io_pushhandle(lua_State *L, int fd, int useshutdown); void moonbr_io_closehandle(lua_State *L, int idx, int timeout); int moonbr_io_tcpconnect(lua_State *L); +int moonbr_io_tcpconnect_nb(lua_State *L); int luaopen_moonbridge_io(lua_State *L); diff -r acaa85256c4b -r c9ffbdac1337 reference.txt --- a/reference.txt Wed Apr 08 04:00:41 2015 +0200 +++ b/reference.txt Wed Apr 08 04:22:03 2015 +0200 @@ -243,6 +243,16 @@ plus an error message (as second return value) in case of error. +### moonbridge_io.tcpconnect_nb(hostname, port) + +Same as moonbridge_io.tcpconnect(hostname, port), except that this function +does not block and immediately returns a socket object. + +In case of an I/O error, nil (as first return value) plus an error message (as +second result value) may be returned. However, connection errors may also be +reported on first read or write on the socket. + + HTTP module -----------