diff options
author | Denys Vlasenko | 2011-02-11 22:01:33 +0100 |
---|---|---|
committer | Denys Vlasenko | 2011-02-11 22:01:33 +0100 |
commit | f9af3756687840c76d8ba4e34b33916b6e36ca61 (patch) | |
tree | eb5e724f14d3327bec15b6306598d920b2ab45ad /networking/wget.c | |
parent | 8766a791e847fdf1f3f00222f18c18833f40abda (diff) | |
download | busybox-f9af3756687840c76d8ba4e34b33916b6e36ca61.zip busybox-f9af3756687840c76d8ba4e34b33916b6e36ca61.tar.gz |
wget: explain clearerr more clearly
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/networking/wget.c b/networking/wget.c index 4868864..673113b 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 |