freeaddrinfo(ai);
if(r == -1) {
+ /* timeout < 0 - do not wait at all */
if(errno == EINPROGRESS && timeout < 0) {
err = 0;
} else if(errno == EINPROGRESS) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLOUT;
- pfd.revents = 0;
-
- r = poll(&pfd, 1, timeout * 1000);
- if(r == 0) {
- /* Timeout */
- snprintf(errbuf, errbufsize, "Connection attempt timed out");
- close(fd);
- return -1;
- }
+ tvhpoll_event_t ev;
+ tvhpoll_t *efd;
+
+ efd = tvhpoll_create(1);
+ memset(&ev, 0, sizeof(ev));
+ ev.events = TVHPOLL_OUT;
+ ev.fd = fd;
+ ev.data.ptr = &fd;
+ tvhpoll_add(efd, &ev, 1);
+
+ /* minimal timeout is one second */
+ if (timeout < 1)
+ timeout = 0;
+
+ while (1) {
+ r = tvhpoll_wait(efd, &ev, 1, timeout * 1000);
+ if (r > 0)
+ break;
+
+ if (r == 0) { /* Timeout */
+ snprintf(errbuf, errbufsize, "Connection attempt timed out");
+ tvhpoll_destroy(efd);
+ close(fd);
+ return -1;
+ }
- if(r == -1) {
- snprintf(errbuf, errbufsize, "poll() error: %s", strerror(errno));
- close(fd);
- return -1;
+ if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
+ snprintf(errbuf, errbufsize, "poll() error: %s", strerror(errno));
+ tvhpoll_destroy(efd);
+ close(fd);
+ return -1;
+ }
}
-
+
+ tvhpoll_destroy(efd);
getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen);
} else {
err = errno;