diff options
author | Masaki Matsushita <glass.saga@gmail.com> | 2020-09-25 16:20:18 +0900 |
---|---|---|
committer | Masaki Matsushita <glass.saga@gmail.com> | 2020-12-10 20:52:29 +0900 |
commit | 78f188524f551c97b1a7a44ae13514729f1a21c7 (patch) | |
tree | eb334c023f4571b883221cbaa7a149352ac83b9c /ext/socket/init.c | |
parent | 658b4ff60934b9fb6845e214fda83229e631e366 (diff) |
Add connect_timeout to TCPSocket
Add connect_timeout to TCPSocket.new in the same way as Socket.tcp.
Closes [Feature #17187]
Diffstat (limited to 'ext/socket/init.c')
-rw-r--r-- | ext/socket/init.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/ext/socket/init.c b/ext/socket/init.c index 0604e8b72f..af46b8edaa 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -451,7 +451,7 @@ rsock_socket(int domain, int type, int proto) /* emulate blocking connect behavior on EINTR or non-blocking socket */ static int -wait_connectable(int fd) +wait_connectable(int fd, struct timeval *timeout) { int sockerr, revents; socklen_t sockerrlen; @@ -488,7 +488,7 @@ wait_connectable(int fd) * * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART */ - revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL); + revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, timeout); if (revents < 0) return -1; @@ -503,6 +503,12 @@ wait_connectable(int fd) * be defensive in case some platforms set SO_ERROR on the original, * interrupted connect() */ + + /* when the connection timed out, no errno is set and revents is 0. */ + if (timeout && revents == 0) { + errno = ETIMEDOUT; + return -1; + } case EINTR: #ifdef ERESTART case ERESTART: @@ -550,7 +556,7 @@ socks_connect_blocking(void *data) #endif int -rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks) +rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout) { int status; rb_blocking_function_t *func = connect_blocking; @@ -574,7 +580,7 @@ rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks) #ifdef EINPROGRESS case EINPROGRESS: #endif - return wait_connectable(fd); + return wait_connectable(fd, timeout); } } return status; |