Beispiel #1
0
struct wget_timer *
wtimer_new (void)
{
  struct wget_timer *wt = wtimer_allocate ();
  wtimer_reset (wt);
  return wt;
}
Beispiel #2
0
/* 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;
}