]> granicus.if.org Git - curl/commitdiff
src/tool: allow timeouts to accept decimal values
authorDave Reisner <dreisner@archlinux.org>
Tue, 30 Apr 2013 14:23:39 +0000 (14:23 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 14 Jul 2013 21:04:05 +0000 (23:04 +0200)
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).

docs/curl.1
src/tool_cfgable.h
src/tool_getparam.c
src/tool_operate.c
src/tool_paramhlp.c
src/tool_paramhlp.h

index 0d0e12f9199630053c1eae27a4efd41527bc7e82..9e1a6883b37a054089b8d06c83fe040a8a26288e 100644 (file)
@@ -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>"
index e6611fca07fc0b77e3addae34837515b003e81d8..9a9b6d8d30f1e942a367a6f6e280ae6ac038e581 100644 (file)
@@ -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;
index fb8270894f7c0314c931f63ac02ba1f5d6761f04..5eb2c9f83f4f036c483906ff6816c9e737c58e4b 100644 (file)
@@ -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;
index 3a15bed511f93a84e9d1269da147bd24d2cbef02..9c2fd3847c7bbac5195d2edea1fd41a6cc29cf93 100644 (file)
@@ -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);
index d2324504628645c5f72577f88eb2143525a70b04..86b8a1df5426538985ce322905322ca98e885aa7 100644 (file)
@@ -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.
index de1604e90528373078e1924de91e310ca27a539c..24734a5200aebb0520c42c4d524ed17ff14ff230 100644 (file)
@@ -33,6 +33,8 @@ void cleanarg(char *str);
 
 ParameterError str2num(long *val, const char *str);
 ParameterError str2unum(long *val, const char *str);
+ParameterError str2double(double *val, const char *str);
+ParameterError str2udouble(double *val, const char *str);
 
 long proto2num(struct Configurable *config, long *val, const char *str);