+ if (expected > delta_t)
+ {
+ double slp = expected - delta_t + limit_data.sleep_adjust;
+ double t0, t1;
+ if (slp < 200)
+ {
+ DEBUGP (("deferring a %.2f ms sleep (%s/%.2f).\n",
+ slp, number_to_static_string (limit_data.chunk_bytes),
+ delta_t));
+ return;
+ }
+ DEBUGP (("\nsleeping %.2f ms for %s bytes, adjust %.2f ms\n",
+ slp, number_to_static_string (limit_data.chunk_bytes),
+ limit_data.sleep_adjust));
+
+ t0 = ptimer_read (timer);
+ xsleep (slp / 1000);
+ t1 = ptimer_measure (timer);
+
+ /* Due to scheduling, we probably slept slightly longer (or
+ shorter) than desired. Calculate the difference between the
+ desired and the actual sleep, and adjust the next sleep by
+ that amount. */
+ limit_data.sleep_adjust = slp - (t1 - t0);
+ }
+
+ limit_data.chunk_bytes = 0;
+ limit_data.chunk_start = ptimer_read (timer);
+}
+
+#ifndef MIN
+# define MIN(i, j) ((i) <= (j) ? (i) : (j))
+#endif
+
+/* Write data in BUF to OUT. However, if *SKIP is non-zero, skip that
+ amount of data and decrease SKIP. Increment *TOTAL by the amount
+ of data written. */
+
+static int
+write_data (FILE *out, const char *buf, int bufsize, wgint *skip,
+ wgint *written)
+{
+ if (!out)
+ return 1;
+ if (*skip > bufsize)
+ {
+ *skip -= bufsize;
+ return 1;
+ }
+ if (*skip)
+ {
+ buf += *skip;
+ bufsize -= *skip;
+ *skip = 0;
+ if (bufsize == 0)
+ return 1;
+ }
+
+ fwrite (buf, 1, bufsize, out);
+ *written += bufsize;
+
+ /* Immediately flush the downloaded data. This should not hinder
+ performance: fast downloads will arrive in large 16K chunks
+ (which stdio would write out immediately anyway), and slow
+ downloads wouldn't be limited by disk speed. */
+ fflush (out);
+ return !ferror (out);
+}
+
+/* Read the contents of file descriptor FD until it the connection
+ terminates or a read error occurs. The data is read in portions of
+ up to 16K and written to OUT as it arrives. If opt.verbose is set,
+ the progress is shown.
+
+ TOREAD is the amount of data expected to arrive, normally only used
+ by the progress gauge.
+
+ STARTPOS is the position from which the download starts, used by
+ the progress gauge. If QTYREAD is non-NULL, the value it points to
+ is incremented by the amount of data read from the network. If
+ QTYWRITTEN is non-NULL, the value it points to is incremented by
+ the amount of data written to disk. The time it took to download
+ the data (in milliseconds) is stored to ELAPSED.
+
+ The function exits and returns the amount of data read. In case of
+ error while reading data, -1 is returned. In case of error while
+ writing data, -2 is returned. */