struct wget_timer * wtimer_new (void) { struct wget_timer *wt = wtimer_allocate (); wtimer_reset (wt); return wt; }
/* Reads the contents of file descriptor FD, until it is closed, or a read error occurs. The data is read in 8K chunks, and stored to stream fp, which should have been open for writing. If BUF is non-NULL and its file descriptor is equal to FD, flush RBUF first. This function will *not* use the rbuf_* functions! The EXPECTED argument is passed to show_progress() unchanged, but otherwise ignored. If opt.verbose is set, the progress is also shown. RESTVAL represents a value from which to start downloading (which will be shown accordingly). If RESTVAL is non-zero, the stream should have been open for appending. The function exits and returns codes of 0, -1 and -2 if the connection was closed, there was a read error, or if it could not write to the output stream, respectively. IMPORTANT: The function flushes the contents of the buffer in rbuf_flush() before actually reading from fd. If you wish to read from fd immediately, flush or discard the buffer. */ int get_contents (int fd, FILE *fp, long *len, long restval, long expected, struct rbuf *rbuf, int use_expected, long *elapsed) { int res = 0; static char c[8192]; void *progress = NULL; struct wget_timer *timer = wtimer_allocate (); long dltime = 0, last_dltime = 0; *len = restval; if (opt.verbose) progress = progress_create (restval, expected); if (rbuf && RBUF_FD (rbuf) == fd) { int sz = 0; while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0) { fwrite (c, sizeof (char), res, fp); *len += res; sz += res; } if (sz) fflush (fp); if (ferror (fp)) { res = -2; goto out; } if (opt.verbose) progress_update (progress, sz, 0); } if (opt.limit_rate) limit_bandwidth_reset (); wtimer_reset (timer); /* Read from fd while there is available data. Normally, if expected is 0, it means that it is not known how much data is expected. However, if use_expected is specified, then expected being zero means exactly that. */ while (!use_expected || (*len < expected)) { int amount_to_read = (use_expected ? MIN (expected - *len, sizeof (c)) : sizeof (c)); #ifdef HAVE_SSL if (rbuf->ssl!=NULL) res = ssl_iread (rbuf->ssl, c, amount_to_read); else #endif /* HAVE_SSL */ res = iread (fd, c, amount_to_read); if (res > 0) { fwrite (c, sizeof (char), res, fp); /* Always flush the contents of the network packet. This should not be adverse to performance, as the network packets typically won't be too tiny anyway. */ fflush (fp); if (ferror (fp)) { res = -2; goto out; } /* If bandwidth is not limited, one call to wtimer_elapsed is sufficient. */ dltime = wtimer_elapsed (timer); if (opt.limit_rate) { limit_bandwidth (res, dltime - last_dltime); dltime = wtimer_elapsed (timer); last_dltime = dltime; } if (opt.verbose) progress_update (progress, res, dltime); *len += res; } else break; } if (res < -1) res = -1; out: if (opt.verbose) progress_finish (progress, dltime); if (elapsed) *elapsed = dltime; wtimer_delete (timer); return res; }