| 84 | #endif |
| 85 | } |
| 86 | int connect(int fd, const struct sockaddr *addr, socklen_t addrlen, |
| 87 | Timeout timeout) { |
| 88 | int err = 0; |
| 89 | while (true) { |
| 90 | int ret = ::connect(fd, addr, addrlen); |
| 91 | if (ret < 0) { |
| 92 | auto e = errno; // errno is usually a macro that expands to a |
| 93 | // function call |
| 94 | if (e == EINTR) { |
| 95 | err = 1; |
| 96 | continue; |
| 97 | } |
| 98 | if (e == EINPROGRESS || (e == EADDRINUSE && err == 1)) { |
| 99 | ret = photon::wait_for_fd_writable(fd, timeout); |
| 100 | if (ret < 0) return -1; |
| 101 | socklen_t n = sizeof(err); |
| 102 | ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &n); |
| 103 | if (unlikely(ret < 0)) return -1; |
| 104 | if (err) { |
| 105 | errno = err; |
| 106 | return -1; |
| 107 | } |
| 108 | return 0; |
| 109 | } |
| 110 | } |
| 111 | return ret; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, |
| 116 | Timeout timeout) { |