Commit d8c04909 authored by Dave Reisner's avatar Dave Reisner Committed by Daniel Stenberg
Browse files

src/tool: allow timeouts to accept decimal values

Implement wrappers around strtod to convert the user argument to a
double with sane error checking. Use this to allow --max-time and
--connect-timeout to accept decimal values instead of strictly integers.

The manpage is updated to make mention of this feature and,
additionally, forewarn that the actual timeout of the operation can
vary in its precision (particularly as the value increases in its
decimal precision).
parent c0a7a98a
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -230,7 +230,9 @@ server sends an unsupported encoding, curl will report an error.
.IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is
of no more use. See also the \fI-m, --max-time\fP option.
of no more use.  Since 7.32.0, this option accepts decimal values, but the
actual timeout will decrease in accuracy as the specified timeout increases in
decimal precision. See also the \fI-m, --max-time\fP option.

If this option is used several times, the last one will be used.
.IP "--create-dirs"
@@ -813,7 +815,10 @@ Basic authentication).
.IP "-m, --max-time <seconds>"
Maximum time in seconds that you allow the whole operation to take.  This is
useful for preventing your batch jobs from hanging for hours due to slow
networks or links going down.  See also the \fI--connect-timeout\fP option.
networks or links going down.  Since 7.32.0, this option accepts decimal
values, but the actual timeout will decrease in accuracy as the specified
timeout increases in decimal precision.  See also the \fI--connect-timeout\fP
option.

If this option is used several times, the last one will be used.
.IP "--mail-auth <address>"
+2 −2
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ struct Configurable {
  char *postfields;
  curl_off_t postfieldsize;
  char *referer;
  long timeout;
  long connecttimeout;
  double timeout;
  double connecttimeout;
  long maxredirs;
  curl_off_t max_filesize;
  char *headerfile;
+2 −2
Original line number Diff line number Diff line
@@ -498,7 +498,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
        GetStr(&config->egd_file, nextarg);
        break;
      case 'c': /* connect-timeout */
        err = str2unum(&config->connecttimeout, nextarg);
        err = str2udouble(&config->connecttimeout, nextarg);
        if(err)
          return err;
        break;
@@ -1404,7 +1404,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
      break;
    case 'm':
      /* specified max time */
      err = str2unum(&config->timeout, nextarg);
      err = str2udouble(&config->timeout, nextarg);
      if(err)
        return err;
      break;
+3 −2
Original line number Diff line number Diff line
@@ -946,7 +946,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
        my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
        my_setopt_str(curl, CURLOPT_RANGE, config->range);
        my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
        my_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
        my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));

        if(built_in_protos & CURLPROTO_HTTP) {

@@ -1134,7 +1134,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
        /* new in libcurl 7.7: */
        my_setopt_str(curl, CURLOPT_RANDOM_FILE, config->random_file);
        my_setopt(curl, CURLOPT_EGDSOCKET, config->egd_file);
        my_setopt(curl, CURLOPT_CONNECTTIMEOUT, config->connecttimeout);
        my_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS,
                  (long)(config->connecttimeout * 1000));

        if(config->cipher_list)
          my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
+42 −0
Original line number Diff line number Diff line
@@ -187,6 +187,48 @@ ParameterError str2unum(long *val, const char *str)
  return PARAM_OK;
}

/*
 * Parse the string and write the double in the given address. Return PARAM_OK
 * on success, otherwise a parameter specific error enum.
 *
 * Since this function gets called with the 'nextarg' pointer from within the
 * getparameter a lot, we must check it for NULL before accessing the str
 * data.
 */

ParameterError str2double(double *val, const char *str)
{
  if(str) {
    char *endptr;
    double num = strtod(str, &endptr);
    if((endptr != str) && (endptr == str + strlen(str))) {
      *val = num;
      return PARAM_OK;  /* Ok */
    }
  }
  return PARAM_BAD_NUMERIC; /* badness */
}

/*
 * Parse the string and write the double in the given address. Return PARAM_OK
 * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
 *
 * Since this function gets called with the 'nextarg' pointer from within the
 * getparameter a lot, we must check it for NULL before accessing the str
 * data.
 */

ParameterError str2udouble(double *val, const char *str)
{
  ParameterError result = str2double(val, str);
  if(result != PARAM_OK)
    return result;
  if(*val < 0)
    return PARAM_NEGATIVE_NUMERIC;

  return PARAM_OK;
}

/*
 * Parse the string and modify the long in the given address. Return
 * non-zero on failure, zero on success.
Loading