Date: Wed, 29 Jan 2014 12:48:19 +0000 (UTC) From: Dag-Erling Smørgrav <des@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r261263 - head/lib/libfetch Message-ID: <201401291248.s0TCmJT7045274@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: des Date: Wed Jan 29 12:48:19 2014 New Revision: 261263 URL: http://svnweb.freebsd.org/changeset/base/261263 Log: r261230 broke the cases where the amount of data to be read is not known in advance, or where the caller doesn't care and just keeps reading until it hits EOF. In fetch_read(): the socket is non-blocking, so read() will return 0 on EOF, and -1 (errno == EAGAIN) when the connection is still open but there is no data waiting. In the first case, we should immediately return 0. The EINTR case was also broken, although not in a way that matters. In fetch_writev(): use timersub() and timercmp() as in fetch_read(). In http_fillbuf(): set errno to a sensible value when an invalid chunk header is encountered. In http_readfn(): as in fetch_read(), a zero return from down the stack indicates EOF, not an error. Furthermore, when io->error is EINTR, clear it (but no errno) before returning so the caller can retry after dealing with the interrupt. MFC after: 3 days Modified: head/lib/libfetch/common.c head/lib/libfetch/http.c Modified: head/lib/libfetch/common.c ============================================================================== --- head/lib/libfetch/common.c Wed Jan 29 12:34:05 2014 (r261262) +++ head/lib/libfetch/common.c Wed Jan 29 12:48:19 2014 (r261263) @@ -976,13 +976,13 @@ fetch_read(conn_t *conn, char *buf, size else #endif rlen = fetch_socket_read(conn->sd, buf, len); - if (rlen > 0) { + if (rlen >= 0) { break; } else if (rlen == FETCH_READ_ERROR) { - if (errno == EINTR) - break; + fetch_syserr(); return (-1); } + // assert(rlen == FETCH_READ_WAIT); if (fetchTimeout > 0) { gettimeofday(&now, NULL); if (!timercmp(&timeout, &now, >)) { @@ -1079,7 +1079,7 @@ fetch_writev(conn_t *conn, struct iovec struct timeval now, timeout, delta; struct pollfd pfd; ssize_t wlen, total; - int deltams, r; + int deltams; memset(&pfd, 0, sizeof pfd); if (fetchTimeout) { @@ -1093,20 +1093,17 @@ fetch_writev(conn_t *conn, struct iovec while (iovcnt > 0) { while (fetchTimeout && pfd.revents == 0) { gettimeofday(&now, NULL); - delta.tv_sec = timeout.tv_sec - now.tv_sec; - delta.tv_usec = timeout.tv_usec - now.tv_usec; - if (delta.tv_usec < 0) { - delta.tv_usec += 1000000; - delta.tv_sec--; - } - if (delta.tv_sec < 0) { + if (!timercmp(&timeout, &now, >)) { errno = ETIMEDOUT; fetch_syserr(); return (-1); } - deltams = delta.tv_sec * 1000 + delta.tv_usec / 1000;; + timersub(&timeout, &now, &delta); + deltams = delta.tv_sec * 1000 + + delta.tv_usec / 1000; errno = 0; - if ((r = poll(&pfd, 1, deltams)) == -1) { + pfd.revents = 0; + if (poll(&pfd, 1, deltams) < 0) { if (errno == EINTR && fetchRestartCalls) continue; return (-1); Modified: head/lib/libfetch/http.c ============================================================================== --- head/lib/libfetch/http.c Wed Jan 29 12:34:05 2014 (r261262) +++ head/lib/libfetch/http.c Wed Jan 29 12:48:19 2014 (r261263) @@ -204,7 +204,7 @@ http_growbuf(struct httpio *io, size_t l /* * Fill the input buffer, do chunk decoding on the fly */ -static int +static ssize_t http_fillbuf(struct httpio *io, size_t len) { ssize_t nbytes; @@ -230,7 +230,7 @@ http_fillbuf(struct httpio *io, size_t l if (io->chunksize == 0) { switch (http_new_chunk(io)) { case -1: - io->error = 1; + io->error = EPROTO; return (-1); case 0: io->eof = 1; @@ -276,10 +276,12 @@ http_readfn(void *v, char *buf, int len) /* empty buffer */ if (!io->buf || io->bufpos == io->buflen) { - if (http_fillbuf(io, len) < 1) { - if (io->error == EINTR) + if ((rlen = http_fillbuf(io, len)) < 0) { + if ((errno = io->error) == EINTR) io->error = 0; return (-1); + } else if (rlen == 0) { + return (0); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401291248.s0TCmJT7045274>