moonbridge
changeset 99:c9ffbdac1337
New function moonbridge_io.tcpconnect_nb(...) for nonblocking connects
author | jbe |
---|---|
date | Wed Apr 08 04:22:03 2015 +0200 (2015-04-08) |
parents | acaa85256c4b |
children | df1ab25c6513 |
files | moonbridge_io.c moonbridge_io.h reference.txt |
line diff
1.1 --- a/moonbridge_io.c Wed Apr 08 04:00:41 2015 +0200 1.2 +++ b/moonbridge_io.c Wed Apr 08 04:22:03 2015 +0200 1.3 @@ -484,7 +484,7 @@ 1.4 return 0; 1.5 } 1.6 1.7 -int moonbr_io_tcpconnect(lua_State *L) { 1.8 +static int moonbr_io_tcpconnect_impl(lua_State *L, int nonblocking) { 1.9 const char *host, *port; 1.10 struct addrinfo hints = { 0, }; 1.11 struct addrinfo *res, *addrinfo; 1.12 @@ -516,22 +516,42 @@ 1.13 } 1.14 addrinfo = res; 1.15 moonbr_io_tcpconnect_found: 1.16 - sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); 1.17 + sock = socket( 1.18 + addrinfo->ai_family, 1.19 + addrinfo->ai_socktype | SOCK_CLOEXEC | (nonblocking ? SOCK_NONBLOCK : 0), 1.20 + addrinfo->ai_protocol 1.21 + ); 1.22 if (sock < 0) { 1.23 moonbr_io_errmsg(); 1.24 lua_pushnil(L); 1.25 lua_pushstring(L, errmsg); 1.26 } 1.27 if (connect(sock, addrinfo->ai_addr, addrinfo->ai_addrlen)) { 1.28 - moonbr_io_errmsg(); 1.29 - lua_pushnil(L); 1.30 - lua_pushstring(L, errmsg); 1.31 - return 2; 1.32 + if (!nonblocking && errno == EINTR) { 1.33 + moonbr_io_errmsg(); 1.34 + close(sock); 1.35 + lua_pushnil(L); 1.36 + lua_pushstring(L, errmsg); 1.37 + return 2; 1.38 + } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) { 1.39 + moonbr_io_errmsg(); 1.40 + lua_pushnil(L); 1.41 + lua_pushstring(L, errmsg); 1.42 + return 2; 1.43 + } 1.44 } 1.45 moonbr_io_pushhandle(L, sock, 1); 1.46 return 1; 1.47 } 1.48 1.49 +static int moonbr_io_tcpconnect(lua_State *L) { 1.50 + return moonbr_io_tcpconnect_impl(L, 0); 1.51 +} 1.52 + 1.53 +static int moonbr_io_tcpconnect_nb(lua_State *L) { 1.54 + return moonbr_io_tcpconnect_impl(L, 1); 1.55 +} 1.56 + 1.57 static const struct luaL_Reg moonbr_io_handle_methods[] = { 1.58 {"read", moonbr_io_read}, 1.59 {"read_nb", moonbr_io_read_nb}, 1.60 @@ -556,6 +576,7 @@ 1.61 1.62 static const struct luaL_Reg moonbr_io_module_funcs[] = { 1.63 {"tcpconnect", moonbr_io_tcpconnect}, 1.64 + {"tcpconnect_nb", moonbr_io_tcpconnect_nb}, 1.65 {NULL, NULL} 1.66 }; 1.67
2.1 --- a/moonbridge_io.h Wed Apr 08 04:00:41 2015 +0200 2.2 +++ b/moonbridge_io.h Wed Apr 08 04:22:03 2015 +0200 2.3 @@ -2,5 +2,6 @@ 2.4 void moonbr_io_pushhandle(lua_State *L, int fd, int useshutdown); 2.5 void moonbr_io_closehandle(lua_State *L, int idx, int timeout); 2.6 int moonbr_io_tcpconnect(lua_State *L); 2.7 +int moonbr_io_tcpconnect_nb(lua_State *L); 2.8 int luaopen_moonbridge_io(lua_State *L); 2.9
3.1 --- a/reference.txt Wed Apr 08 04:00:41 2015 +0200 3.2 +++ b/reference.txt Wed Apr 08 04:22:03 2015 +0200 3.3 @@ -243,6 +243,16 @@ 3.4 plus an error message (as second return value) in case of error. 3.5 3.6 3.7 +### moonbridge_io.tcpconnect_nb(hostname, port) 3.8 + 3.9 +Same as moonbridge_io.tcpconnect(hostname, port), except that this function 3.10 +does not block and immediately returns a socket object. 3.11 + 3.12 +In case of an I/O error, nil (as first return value) plus an error message (as 3.13 +second result value) may be returned. However, connection errors may also be 3.14 +reported on first read or write on the socket. 3.15 + 3.16 + 3.17 3.18 HTTP module 3.19 -----------