[Bug 5426] wget hangs in call to poll() if progress meter or timeout support is enabled and HTTP chunked encoding is used
bugzilla at busybox.net
bugzilla at busybox.net
Mon Sep 3 09:19:29 UTC 2012
https://bugs.busybox.net/show_bug.cgi?id=5426
--- Comment #5 from Kenneth Soerensen <knnthsrnsn at gmail.com> 2012-09-03 09:19:28 UTC ---
It is correct that the delay is one second. However, if you are unlucky like
the example PCAP I attached you can get the delay for every chunk.
I suggest a solution where you always call fread() before calling poll() and
only call poll() if the fread() returns EAGAIN.
Below patch should do this:
=================
diff --git a/networking/wget.c b/networking/wget.c
index 3416636..74a2a5f 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -485,64 +485,62 @@ static void NOINLINE retrieve_file_data(FILE *dfp)
}
}
-#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
- if (safe_poll(&polldata, 1, 1000) == 0) {
-# if ENABLE_FEATURE_WGET_TIMEOUT
- if (second_cnt != 0 && --second_cnt == 0) {
- progress_meter(PROGRESS_END);
- bb_error_msg_and_die("download timed out");
- }
-# endif
- /* Needed for "stalled" indicator */
- progress_meter(PROGRESS_BUMP);
- /*
- * We used to loop back to poll here,
- * but in chunked case, we can be here after
- * fgets and it could buffer some data in dfp...
- * which poll knows nothing about!
- * Therefore let's try fread'ing anyway.
- */
- }
-
- /* 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.
- * Need to clear it before next fread to avoid possible
- * rare false positive ferror below. Rare because usually
- * fread gets more than zero bytes, and we don't fall
- * into if (n <= 0) ...
- */
- 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
* is a short item count (or zero).
* fread does not distinguish between EOF and error.
*/
- if (n <= 0) {
-#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
- if (errno == EAGAIN) /* poll lied, there is no data? */
- continue; /* yes */
-#endif
- if (ferror(dfp))
- bb_perror_msg_and_die(bb_msg_read_error);
- break; /* EOF, not error */
- }
-
- xwrite(G.output_fd, G.wget_buf, n);
+ if (n > 0) {
+ xwrite(G.output_fd, G.wget_buf, n);
#if ENABLE_FEATURE_WGET_TIMEOUT
- second_cnt = G.timeout_seconds;
+ second_cnt = G.timeout_seconds;
#endif
#if ENABLE_FEATURE_WGET_STATUSBAR
- G.transferred += n;
- progress_meter(PROGRESS_BUMP);
+ G.transferred += n;
+ progress_meter(PROGRESS_BUMP);
#endif
- if (G.got_clen) {
- G.content_len -= n;
- if (G.content_len == 0)
- break;
+ if (G.got_clen) {
+ G.content_len -= n;
+ if (G.content_len == 0)
+ break;
+ }
+ }
+#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
+ else if (errno == EAGAIN) {
+ if (safe_poll(&polldata, 1, 1000) == 0) {
+# if ENABLE_FEATURE_WGET_TIMEOUT
+ if (second_cnt != 0 && --second_cnt == 0) {
+ progress_meter(PROGRESS_END);
+ bb_error_msg_and_die("download timed out");
+ }
+# endif
+ /* Needed for "stalled" indicator */
+ progress_meter(PROGRESS_BUMP);
+ /*
+ * We used to loop back to poll here,
+ * but in chunked case, we can be here after
+ * fgets and it could buffer some data in dfp...
+ * which poll knows nothing about!
+ * Therefore let's try fread'ing anyway.
+ */
+ }
+
+ /* 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.
+ * Need to clear it before next fread to avoid possible
+ * rare false positive ferror below. Rare because usually
+ * fread gets more than zero bytes, and we don't fall
+ * into if (n <= 0) ...
+ */
+ clearerr(dfp);
+ errno = 0;
+ }
+#endif
+ else {
+ if (ferror(dfp))
+ bb_perror_msg_and_die(bb_msg_read_error);
}
}
#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
--
=================
--
Configure bugmail: https://bugs.busybox.net/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the busybox-cvs
mailing list