From f9af3756687840c76d8ba4e34b33916b6e36ca61 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 11 Feb 2011 22:01:33 +0100 Subject: [PATCH] wget: explain clearerr more clearly Signed-off-by: Denys Vlasenko --- networking/wget.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/networking/wget.c b/networking/wget.c index 48688640a..673113bfc 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -466,6 +466,14 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) polldata.fd = fileno(dfp); polldata.events = POLLIN | POLLPRI; + + /* Must use nonblocking I/O, otherwise fread will loop + * and *block* until it reads full buffer, + * which messes up progress bar and/or timing out. + * Because of nonblocking I/O, we need to dance + * very carefully around EAGAIN. See explanation at + * clearerr() call. + */ ndelay_on(polldata.fd); #endif progress_meter(PROGRESS_START); @@ -504,7 +512,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) /* Needed for "stalled" indicator */ progress_meter(PROGRESS_BUMP); } -#endif + /* fread internally uses read loop, which in our case * is usually exited when we get EAGAIN. * In this case, libc sets error marker on the stream. @@ -515,6 +523,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) */ clearerr(dfp); errno = 0; +#endif n = fread(G.wget_buf, 1, rdsz, dfp); /* man fread: * If error occurs, or EOF is reached, the return value