]> sjero.net Git - wget/commitdiff
[svn] Allow decimal values for --timeout, --wait, and --waitretry.
authorhniksic <devnull@localhost>
Sat, 20 Sep 2003 23:12:18 +0000 (16:12 -0700)
committerhniksic <devnull@localhost>
Sat, 20 Sep 2003 23:12:18 +0000 (16:12 -0700)
Message-ID: <m3llsjhx6t.fsf@hniksic.iskon.hr>

12 files changed:
src/ChangeLog
src/connect.c
src/connect.h
src/host.c
src/init.c
src/mswindows.c
src/mswindows.h
src/options.h
src/retr.c
src/sysdep.h
src/utils.c
src/utils.h

index 7f64e35f7d5df9c77952e5e7142ca993e1455a4a..a2d4d7b52330fc34b74b9d8c5751cc989e4fcb31 100644 (file)
@@ -1,3 +1,20 @@
+2003-09-21  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * connect.c (select_fd): Change MAXTIME's type to double.  Handle
+       its decimal part.
+
+       * retr.c (sleep_between_retrievals): In the random-wait case, use
+       random_float() to wait between 0 and 2*opt.wait seconds.
+
+       * utils.c (run_with_timeout): Accept `double' timeouts.  Correctly
+       handle timeout values in (0, 1) range.
+       (random_float): New function.
+
+       * options.h (struct options): Change the types of wait, waitretry,
+       and timeout to double.
+
+       * init.c (cmd_time): Accept floating point time.
+
 2003-09-20  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * retr.c (get_contents): Cosmetic fixes.
index 7ac7d3fba1321d135a47eb431330d0e91bd6660f..5f927647079acfba2aacba40072182f07532eb38 100644 (file)
@@ -355,7 +355,7 @@ bindport (unsigned short *port, int family)
    Returns 1 if FD is available, 0 for timeout and -1 for error.  */
 
 int
-select_fd (int fd, int maxtime, int writep)
+select_fd (int fd, double maxtime, int writep)
 {
   fd_set fds;
   fd_set *rd = NULL, *wrt = NULL;
@@ -366,8 +366,8 @@ select_fd (int fd, int maxtime, int writep)
   FD_SET (fd, &fds);
   *(writep ? &wrt : &rd) = &fds;
 
-  tmout.tv_sec = maxtime;
-  tmout.tv_usec = 0;
+  tmout.tv_sec = (long)maxtime;
+  tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
 
   do
     result = select (fd + 1, rd, wrt, NULL, &tmout);
index e19241599d6059d421e3afddfdd7d8b05bc027c5..75eb9caaa2f5ba8ff3aadbf4f345e6108c6782a1 100644 (file)
@@ -39,7 +39,7 @@ int connect_to_many PARAMS ((struct address_list *, unsigned short, int));
 void set_connection_host_name PARAMS ((const char *));
 
 int test_socket_open PARAMS ((int));
-int select_fd PARAMS ((int, int, int));
+int select_fd PARAMS ((int, double, int));
 uerr_t bindport PARAMS ((unsigned short *, int));
 uerr_t acceptport PARAMS ((int *));
 void closeport PARAMS ((int));
index 12b80602146f4b615c761ae2fea3106a650d3200..baae0f3870962e9646d1aebea388da3342b04eb5 100644 (file)
@@ -494,7 +494,7 @@ gethostbyname_with_timeout_callback (void *arg)
    other than timeout, errno is reset.  */
 
 static struct hostent *
-gethostbyname_with_timeout (const char *host_name, int timeout)
+gethostbyname_with_timeout (const char *host_name, double timeout)
 {
   struct ghbnwt_context ctx;
   ctx.host_name = host_name;
@@ -533,7 +533,7 @@ getaddrinfo_with_timeout_callback (void *arg)
 static int
 getaddrinfo_with_timeout (const char *node, const char *service,
                          const struct addrinfo *hints, struct addrinfo **res,
-                         int timeout)
+                         double timeout)
 {
   struct gaiwt_context ctx;
   ctx.node = node;
@@ -670,7 +670,8 @@ lookup_host (const char *host, int silent)
   }
 #else
   {
-    struct hostent *hptr = gethostbyname_with_timeout (host, opt.timeout);
+    struct hostent *hptr;
+    hptr = gethostbyname_with_timeout (host, opt.timeout);
     if (!hptr)
       {
        if (!silent)
index 59a2aab9bf14af3d43b2cc5f540d9be5a92a7b2f..321e2d42b22afe1826e8aaf996a6533b8ebf67a5 100644 (file)
@@ -856,51 +856,89 @@ cmd_bytes (const char *com, const char *val, void *closure)
   return 1;
 }
 
-/* Store the value of VAL to *OUT, allowing suffixes for minutes and
-   hours.  */
+/* Store the value of VAL to *OUT.  The value is a time period, by
+   default expressed in seconds.  */
+
 static int
 cmd_time (const char *com, const char *val, void *closure)
 {
-  long result = 0;
-  const char *p = val;
+  double result, mult, divider;
+  int seen_dot, seen_digit;
 
-  /* Search for digits and construct result.  */
-  for (; *p && ISDIGIT (*p); p++)
-    result = (10 * result) + (*p - '0');
-  /* If no digits were found, or more than one character is following
-     them, bail out.  */
-  if (p == val || (*p != '\0' && *(p + 1) != '\0'))
+  const char *p;
+  const char *end = val + strlen (val);
+
+  /* Skip trailing whitespace.  */
+  while (end > val && ISSPACE (end[-1]))
+    --end;
+
+  if (val == end)
     {
-      printf (_("%s: Invalid specification `%s'\n"), com, val);
+    err:
+      fprintf (stderr, _("%s: Invalid time specification `%s'\n"), com, val);
       return 0;
     }
-  /* Search for a suffix.  */
-  switch (TOLOWER (*p))
+
+  switch (TOLOWER (end[-1]))
     {
-    case '\0':
-      /* None */
+    case 's':
+      --end, mult = 1;         /* seconds */
       break;
     case 'm':
-      /* Minutes */
-      result *= 60;
+      --end, mult = 60;                /* minutes */
       break;
     case 'h':
-      /* Seconds */
-      result *= 3600;
+      --end, mult = 3600;      /* hours */
       break;
     case 'd':
-      /* Days (overflow on 16bit machines) */
-      result *= 86400L;
+      --end, mult = 86400;     /* days */
       break;
     case 'w':
-      /* Weeks :-) */
-      result *= 604800L;
+      --end, mult = 604800;    /* weeks */
       break;
     default:
-      printf (_("%s: Invalid specification `%s'\n"), com, val);
-      return 0;
+      /* Not a recognized suffix: treat it as part of number, and
+        assume seconds. */
+      mult = 1;
+    }
+
+  /* Skip leading and trailing whitespace. */
+  while (val < end && ISSPACE (*val))
+    ++val;
+  while (val > end && ISSPACE (end[-1]))
+    --end;
+  if (val == end)
+    goto err;
+
+  /* Poor man's strtod: */
+  result = 0;
+  seen_dot = seen_digit = 0;
+  divider = 1;
+
+  p = val;
+  while (p < end)
+    {
+      char ch = *p++;
+      if (ISDIGIT (ch))
+       {
+         if (!seen_dot)
+           result = (10 * result) + (ch - '0');
+         else
+           result += (ch - '0') / (divider *= 10);
+         seen_digit = 1;
+       }
+      else if (ch == '.')
+       {
+         if (!seen_dot)
+           seen_dot = 1;
+         else
+           goto err;
+       }
     }
-  *(long *)closure = result;
+  if (!seen_digit)
+    goto err;
+  result *= mult;
+  *(double *)closure = result;
   return 1;
 }
 \f
index 53219812e332c93ea1480c67de83a075a0214624..6cfc0555439e430822b50d7b7d9907922ce41a66 100644 (file)
@@ -74,7 +74,8 @@ sleep (unsigned seconds)
 /* Emulation of Unix usleep().  This has a granularity of
    milliseconds, but that's ok because:
 
-   a) Wget is only using it with milliseconds;
+   a) Wget is only using it with milliseconds [not anymore, but b)
+      still applies];
 
    b) You can't rely on usleep's granularity anyway.  If a caller
    expects usleep to respect every microsecond, he's in for a
index 9a7a97f064a99890145a05eded2fbe534144132d..72fe8e96abe2caad70185fcaa70e8c40ea35590d 100644 (file)
@@ -133,5 +133,6 @@ void ws_changetitle (char*, int);
 char *ws_mypath (void);
 void ws_help (const char *);
 void windows_main_junk (int *, char **, char **);
+int usleep (unsigned long);
 
 #endif /* MSWINDOWS_H */
index 5cb749f01d7d6bd580312a5441f4903ff9ee0854..7b67169c056fd8cc7fd4b1df3495a7df35a7c902 100644 (file)
@@ -108,12 +108,11 @@ struct options
   char *proxy_user; /*oli*/
   char *proxy_passwd;
 #ifdef HAVE_SELECT
-  long timeout;                        /* The value of read timeout in
-                                  seconds. */
+  double timeout;              /* The read/connect/DNS timeout. */
 #endif
   int random_wait;             /* vary from 0 .. wait secs by random()? */
-  long wait;                   /* The wait period between retrievals. */
-  long waitretry;              /* The wait period between retries. - HEH */
+  double wait;                 /* The wait period between retrievals. */
+  double waitretry;            /* The wait period between retries. - HEH */
   int use_robots;              /* Do we heed robots.txt? */
 
   long limit_rate;             /* Limit the download rate to this
index 24b0782bfb57445300dffcd0d31d99404d5d2155..051115626ddde5c7f3ce2170959e33fae1a3af54 100644 (file)
@@ -80,7 +80,7 @@ limit_bandwidth_reset (void)
 
 /* Limit the bandwidth by pausing the download for an amount of time.
    BYTES is the number of bytes received from the network, and DELTA
-   is how long it took to receive them.  */
+   is the number of milliseconds it took to receive them.  */
 
 static void
 limit_bandwidth (long bytes, double delta)
@@ -648,7 +648,7 @@ sleep_between_retrievals (int count)
       if (count <= opt.waitretry)
        sleep (count - 1);
       else
-       sleep (opt.waitretry);
+       usleep (1000000L * opt.waitretry);
     }
   else if (opt.wait)
     {
@@ -656,19 +656,16 @@ sleep_between_retrievals (int count)
        /* If random-wait is not specified, or if we are sleeping
           between retries of the same download, sleep the fixed
           interval.  */
-       sleep (opt.wait);
+       usleep (1000000L * opt.wait);
       else
        {
          /* Sleep a random amount of time averaging in opt.wait
             seconds.  The sleeping amount ranges from 0 to
             opt.wait*2, inclusive.  */
-         int waitsecs = random_number (opt.wait * 2 + 1);
-
-         DEBUGP (("sleep_between_retrievals: norm=%ld,fuzz=%ld,sleep=%d\n",
-                  opt.wait, waitsecs - opt.wait, waitsecs));
-
-         if (waitsecs)
-           sleep (waitsecs);
+         double waitsecs = 2 * opt.wait * random_float ();
+         DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
+                  opt.wait, waitsecs));
+         usleep (1000000L * waitsecs);
        }
     }
 }
index 271c5453eba9bd1b001ccabf9c41b4f01ebdd896..c47a243f84639bf212028d4a16813b78bd798459 100644 (file)
@@ -154,7 +154,8 @@ do {                                                \
 # define VERY_LONG_TYPE   unsigned long long
 #endif /* use long long */
 
-/* Defined in cmpt.c: */
+/* These are defined in cmpt.c if missing, therefore it's generally
+   safe to declare their parameters.  */
 #ifndef HAVE_STRERROR
 char *strerror ();
 #endif
@@ -174,7 +175,7 @@ char *strptime ();
 int vsnprintf ();
 #endif
 #ifndef HAVE_USLEEP
-int usleep ();
+int usleep PARAMS ((unsigned long));
 #endif
 #ifndef HAVE_MEMMOVE
 void *memmove ();
index bb45665f745527d7e13832298f39fc35718c40b7..85274e9902ebbe85e20600f472c09dd7ab6df6af 100644 (file)
@@ -1879,6 +1879,22 @@ random_number (int max)
   return (int)bounded;
 }
 
+/* Return a random uniformly distributed floating point number in the
+   [0, 1) range.  The precision of returned numbers is 9 digits.
+
+   Modify this to use erand48() where available!  */
+
+double
+random_float (void)
+{
+  /* We can't rely on any specific value of RAND_MAX, but I'm pretty
+     sure it's greater than 1000.  */
+  int rnd1 = random_number (1000);
+  int rnd2 = random_number (1000);
+  int rnd3 = random_number (1000);
+  return rnd1 / 1000.0 + rnd2 / 1000000.0 + rnd3 / 1000000000.0;
+}
+
 #if 0
 /* A debugging function for checking whether an MD5 library works. */
 
@@ -1950,7 +1966,7 @@ abort_run_with_timeout (int sig)
 #endif /* USE_SIGNAL_TIMEOUT */
 
 int
-run_with_timeout (long timeout, void (*fun) (void *), void *arg)
+run_with_timeout (double timeout, void (*fun) (void *), void *arg)
 {
 #ifndef USE_SIGNAL_TIMEOUT
   fun (arg);
@@ -1964,6 +1980,13 @@ run_with_timeout (long timeout, void (*fun) (void *), void *arg)
       return 0;
     }
 
+  /* Calling alarm() rounds TIMEOUT.  If it is smaller than 1, round
+     it to 1, not to 0, because alarm(0) means "never deliver the
+     alarm", i.e. "wait forever", which is not what someone who
+     specifies a 0.5s timeout would expect.  */
+  if (timeout < 1)
+    timeout = 1;
+
   signal (SIGALRM, abort_run_with_timeout);
   if (SETJMP (run_with_timeout_env) != 0)
     {
@@ -1971,7 +1994,7 @@ run_with_timeout (long timeout, void (*fun) (void *), void *arg)
       signal (SIGALRM, SIG_DFL);
       return 1;
     }
-  alarm (timeout);
+  alarm ((int) timeout);
   fun (arg);
 
   /* Preserve errno in case alarm() or signal() modifies it. */
@@ -1983,4 +2006,3 @@ run_with_timeout (long timeout, void (*fun) (void *), void *arg)
   return 0;
 #endif
 }
-
index 18752a5f015cee53501b3791af7dac46d0f5668d..0783602d6c131cde7722081aaebec98889acded6 100644 (file)
@@ -116,7 +116,8 @@ char *html_quote_string PARAMS ((const char *));
 
 int determine_screen_width PARAMS ((void));
 int random_number PARAMS ((int));
+double random_float PARAMS ((void));
 
-int run_with_timeout PARAMS ((long, void (*) (void *), void *));
+int run_with_timeout PARAMS ((double, void (*) (void *), void *));
 
 #endif /* UTILS_H */