* timeout_connect adapted from netcat, via OpenBSD and FreeBSD * Copyright (c) 2001 Eric Jackson */
| 87 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
| 88 | */ |
| 89 | int |
| 90 | timeout_connect(int s, const struct sockaddr *name, socklen_t namelen, |
| 91 | int timeout) |
| 92 | { |
| 93 | struct pollfd pfd; |
| 94 | socklen_t optlen; |
| 95 | int flags, optval; |
| 96 | int ret; |
| 97 | |
| 98 | flags = 0; |
| 99 | if (timeout != -1) { |
| 100 | flags = fcntl(s, F_GETFL, 0); |
| 101 | if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) |
| 102 | return -1; |
| 103 | } |
| 104 | |
| 105 | if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { |
| 106 | pfd.fd = s; |
| 107 | pfd.events = POLLOUT; |
| 108 | if ((ret = poll(&pfd, 1, timeout)) == 1) { |
| 109 | optlen = sizeof(optval); |
| 110 | if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, |
| 111 | &optval, &optlen)) == 0) { |
| 112 | errno = optval; |
| 113 | ret = optval == 0 ? 0 : -1; |
| 114 | } |
| 115 | } else if (ret == 0) { |
| 116 | errno = ETIMEDOUT; |
| 117 | ret = -1; |
| 118 | } else |
| 119 | ret = -1; |
| 120 | } |
| 121 | |
| 122 | if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) |
| 123 | ret = -1; |
| 124 | |
| 125 | return (ret); |
| 126 | } |
| 127 | |
| 128 | /* netdial and netannounce code comes from libtask: http://swtch.com/libtask/ |
| 129 | * Copyright: http://swtch.com/libtask/COPYRIGHT |
no outgoing calls
no test coverage detected
searching dependent graphs…