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  -----------

Impressum / About Us