/* Await readability (rdwr = 0) or writability (rdwr != 0) for socket * fd for secs seconds. Returns <0 on error, zero on timeout, >0 if * data is available. */ static int raw_poll(int fdno, int rdwr, int secs) { int ret; #ifdef NE_USE_POLL struct pollfd fds; int timeout = secs > 0 ? secs * 1000 : -1; struct timeval startT, nowT; fds.fd = fdno; fds.events = rdwr == 0 ? POLLIN : POLLOUT; fds.revents = 0; gettimeofday(&startT, NULL); do { gettimeofday(&nowT, NULL); ret = poll(&fds, 1, timeout); } while (ret < 0 && NE_ISINTR(ne_errno) && (nowT.tv_sec - startT.tv_sec) < secs); #else fd_set rdfds, wrfds, efds; struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL); struct timeval startT, nowT; /* Init the fd set */ FD_ZERO(&rdfds); FD_ZERO(&wrfds); FD_ZERO(&efds); if (rdwr == 0) FD_SET(fdno, &rdfds); else FD_SET(fdno, &wrfds); FD_SET(fdno, &efds); if (tvp) { tvp->tv_sec = secs; tvp->tv_usec = 0; } gettimeofday(&startT, NULL); do { gettimeofday(&nowT, NULL); ret = select(fdno + 1, &rdfds, &wrfds, &efds, tvp); } while (ret < 0 && NE_ISINTR(ne_errno) && (nowT.tv_sec - startT.tv_sec) < secs); #endif if (ret < 0) { printf("Sorry, http timed out with error %ld\n", nowT.tv_sec - startT.tv_sec); } return ret; }
/* Perform a connect() for given fd, handling EINTR retries. Returns * zero on success or -1 on failure, in which case, ne_errno is set * appropriately. */ static int raw_connect(int fd, const struct sockaddr *sa, size_t salen) { int ret; do { ret = connect(fd, sa, salen); } while (ret < 0 && NE_ISINTR(ne_errno)); return ret; }
/* Await readability (rdwr = 0) or writability (rdwr != 0) for socket * fd for secs seconds. Returns <0 on error, zero on timeout, >0 if * data is available. */ static int raw_poll(int fdno, int rdwr, int secs) { int ret; #ifdef NE_USE_POLL struct pollfd fds; int timeout = secs > 0 ? secs * 1000 : -1; fds.fd = fdno; fds.events = rdwr == 0 ? POLLIN : POLLOUT; fds.revents = 0; do { ret = poll(&fds, 1, timeout); } while (ret < 0 && NE_ISINTR(ne_errno)); #else fd_set rdfds, wrfds; struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL); /* Init the fd set */ FD_ZERO(&rdfds); FD_ZERO(&wrfds); /* Note that (amazingly) the FD_SET macro does not expand * correctly on Netware if not inside a compound statement * block. */ if (rdwr == 0) { FD_SET(fdno, &rdfds); } else { FD_SET(fdno, &wrfds); } if (tvp) { tvp->tv_sec = secs; tvp->tv_usec = 0; } do { ret = select(fdno + 1, &rdfds, &wrfds, NULL, tvp); } while (ret < 0 && NE_ISINTR(ne_errno)); #endif return ret; }
static ssize_t write_raw(ne_socket *sock, const char *data, size_t length) { ssize_t wrote; do { wrote = ne_write(sock->fd, data, length); if (wrote > 0) { data += wrote; length -= wrote; } } while ((wrote > 0 || NE_ISINTR(ne_errno)) && length > 0); if (wrote < 0) { int errnum = ne_errno; set_strerror(sock, errnum); return MAP_ERR(errnum); } return 0; }
static ssize_t write_raw(ne_socket *sock, const char *data, size_t length) { ssize_t ret; #ifdef __QNX__ /* Test failures seen on QNX over loopback, if passing large * buffer lengths to send(). */ if (length > 8192) length = 8192; #endif do { ret = send(sock->fd, data, length, 0); } while (ret == -1 && NE_ISINTR(ne_errno)); if (ret < 0) { int errnum = ne_errno; set_strerror(sock, errnum); return MAP_ERR(errnum); } return ret; }
static ssize_t read_raw(ne_socket *sock, char *buffer, size_t len) { ssize_t ret; ret = readable_raw(sock, sock->rdtimeout); if (ret) return ret; do { ret = recv(sock->fd, buffer, len, 0); } while (ret == -1 && NE_ISINTR(ne_errno)); if (ret == 0) { set_error(sock, _("Connection closed")); ret = NE_SOCK_CLOSED; } else if (ret < 0) { int errnum = ne_errno; ret = NE_ISRESET(errnum) ? NE_SOCK_RESET : NE_SOCK_ERROR; set_strerror(sock, errnum); } return ret; }
/* Await data on raw fd in socket. */ static int readable_raw(ne_socket *sock, int secs) { int fdno = sock->fd, ret; fd_set rdfds; struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL); /* Init the fd set */ FD_ZERO(&rdfds); do { FD_SET(fdno, &rdfds); if (tvp) { tvp->tv_sec = secs; tvp->tv_usec = 0; } ret = select(fdno + 1, &rdfds, NULL, NULL, tvp); } while (ret < 0 && NE_ISINTR(ne_errno)); if (ret < 0) { set_strerror(sock, ne_errno); return NE_SOCK_ERROR; } return (ret == 0) ? NE_SOCK_TIMEOUT : 0; }