summaryrefslogtreecommitdiffstats
path: root/lib/libfetch/http.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2012-01-18 15:13:21 +0000
committerdes <des@FreeBSD.org>2012-01-18 15:13:21 +0000
commit939a66af62dc031d0ca35b5e7b1410f8aedc1d7c (patch)
treea2005365ba56694fd925cd9d8f2687ea003a376f /lib/libfetch/http.c
parent7972e45b2052402d891e3dd144472547dac25ec6 (diff)
downloadFreeBSD-src-939a66af62dc031d0ca35b5e7b1410f8aedc1d7c.zip
FreeBSD-src-939a66af62dc031d0ca35b5e7b1410f8aedc1d7c.tar.gz
Fix two issues related to the use of SIGINFO in fetch(1) to display
progress information. The first is that fetch_read() (used in the HTTP code but not the FTP code) can enter an infinite loop if it has previously been interrupted by a signal. The second is that when it is interrupted, fetch_read() will discard any data it may have read up to that point. Luckily, both bugs are extremely timing-sensitive and therefore difficult to trigger. PR: bin/153240 Submitted by: Mark <markjdb@gmail.com> MFC after: 3 weeks
Diffstat (limited to 'lib/libfetch/http.c')
-rw-r--r--lib/libfetch/http.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index b33d6f1..557ff26 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -196,6 +196,8 @@ http_growbuf(struct httpio *io, size_t len)
static int
http_fillbuf(struct httpio *io, size_t len)
{
+ ssize_t nbytes;
+
if (io->error)
return (-1);
if (io->eof)
@@ -204,10 +206,11 @@ http_fillbuf(struct httpio *io, size_t len)
if (io->chunked == 0) {
if (http_growbuf(io, len) == -1)
return (-1);
- if ((io->buflen = fetch_read(io->conn, io->buf, len)) == -1) {
- io->error = 1;
+ if ((nbytes = fetch_read(io->conn, io->buf, len)) == -1) {
+ io->error = errno;
return (-1);
}
+ io->buflen = nbytes;
io->bufpos = 0;
return (io->buflen);
}
@@ -227,10 +230,11 @@ http_fillbuf(struct httpio *io, size_t len)
len = io->chunksize;
if (http_growbuf(io, len) == -1)
return (-1);
- if ((io->buflen = fetch_read(io->conn, io->buf, len)) == -1) {
- io->error = 1;
+ if ((nbytes = fetch_read(io->conn, io->buf, len)) == -1) {
+ io->error = errno;
return (-1);
}
+ io->buflen = nbytes;
io->chunksize -= io->buflen;
if (io->chunksize == 0) {
@@ -272,8 +276,11 @@ http_readfn(void *v, char *buf, int len)
io->bufpos += l;
}
- if (!pos && io->error)
+ if (!pos && io->error) {
+ if (io->error == EINTR)
+ io->error = 0;
return (-1);
+ }
return (pos);
}
OpenPOWER on IntegriCloud