]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
timediff.[ch]: add curlx helper functions for timeval conversions
authorMarc Hoersken <info@marc-hoersken.de>
Sat, 29 Aug 2020 10:54:30 +0000 (12:54 +0200)
committerMarc Hoersken <info@marc-hoersken.de>
Sun, 17 Apr 2022 11:11:27 +0000 (13:11 +0200)
Also move timediff_t definitions from timeval.h to timediff.h and
then make timeval.h include the new standalone-capable timediff.h.

Reviewed-by: Jay Satiro
Reviewed-by: Daniel Stenberg
Supersedes #5888
Closes #8595

16 files changed:
lib/Makefile.inc
lib/asyn-ares.c
lib/select.c
lib/timediff.c [new file with mode: 0644]
lib/timediff.h [new file with mode: 0644]
lib/timeval.h
lib/vtls/gskit.c
projects/generate.bat
src/Makefile.inc
tests/libtest/Makefile.inc
tests/libtest/first.c
tests/libtest/lib1507.c
tests/libtest/lib1531.c
tests/libtest/lib1905.c
tests/server/Makefile.inc
tests/server/sockfilt.c

index cfd56d719bc24bbb37a398d21c3a2c9addc9b532..1ab00789660ca6829085aa7f4d821404bca15d38 100644 (file)
@@ -207,6 +207,7 @@ LIB_CFILES =         \
   system_win32.c     \
   telnet.c           \
   tftp.c             \
+  timediff.c         \
   timeval.c          \
   transfer.c         \
   url.c              \
@@ -327,6 +328,7 @@ LIB_HFILES =         \
   system_win32.h     \
   telnet.h           \
   tftp.h             \
+  timediff.h         \
   timeval.h          \
   transfer.h         \
   url.h              \
index fd0bb6c96a250d3ce9ad574051e006b43204bb99..5857b99e4bab4398eda1d50020412f900bf23541 100644 (file)
@@ -65,6 +65,7 @@
 #include "connect.h"
 #include "select.h"
 #include "progress.h"
+#include "timediff.h"
 
 #  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) &&   \
   defined(WIN32)
@@ -290,7 +291,7 @@ int Curl_resolver_getsock(struct Curl_easy *data,
 
   timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
                          &timebuf);
-  milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
+  milli = (long)curlx_tvtoms(timeout);
   if(milli == 0)
     milli += 10;
   Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
index 1de207725f873f04ef20782c96c8d8084c3744fc..a48da82bacc174ea120db90337be70823e84fdf0 100644 (file)
@@ -43,7 +43,7 @@
 #include "urldata.h"
 #include "connect.h"
 #include "select.h"
-#include "timeval.h"
+#include "timediff.h"
 #include "warnless.h"
 
 /*
@@ -93,26 +93,7 @@ int Curl_wait_ms(timediff_t timeout_ms)
 #else
   {
     struct timeval pending_tv;
-    timediff_t tv_sec = timeout_ms / 1000;
-    timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
-#ifdef HAVE_SUSECONDS_T
-#if TIMEDIFF_T_MAX > TIME_T_MAX
-    /* tv_sec overflow check in case time_t is signed */
-    if(tv_sec > TIME_T_MAX)
-      tv_sec = TIME_T_MAX;
-#endif
-    pending_tv.tv_sec = (time_t)tv_sec;
-    pending_tv.tv_usec = (suseconds_t)tv_usec;
-#else
-#if TIMEDIFF_T_MAX > INT_MAX
-    /* tv_sec overflow check in case time_t is signed */
-    if(tv_sec > INT_MAX)
-      tv_sec = INT_MAX;
-#endif
-    pending_tv.tv_sec = (int)tv_sec;
-    pending_tv.tv_usec = (int)tv_usec;
-#endif
-    r = select(0, NULL, NULL, NULL, &pending_tv);
+    r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms));
   }
 #endif /* HAVE_POLL_FINE */
 #endif /* USE_WINSOCK */
@@ -152,43 +133,7 @@ static int our_select(curl_socket_t maxfd,   /* highest socket number */
   }
 #endif
 
-  ptimeout = &pending_tv;
-  if(timeout_ms < 0) {
-    ptimeout = NULL;
-  }
-  else if(timeout_ms > 0) {
-    timediff_t tv_sec = timeout_ms / 1000;
-    timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
-#ifdef HAVE_SUSECONDS_T
-#if TIMEDIFF_T_MAX > TIME_T_MAX
-    /* tv_sec overflow check in case time_t is signed */
-    if(tv_sec > TIME_T_MAX)
-      tv_sec = TIME_T_MAX;
-#endif
-    pending_tv.tv_sec = (time_t)tv_sec;
-    pending_tv.tv_usec = (suseconds_t)tv_usec;
-#elif defined(WIN32) /* maybe also others in the future */
-#if TIMEDIFF_T_MAX > LONG_MAX
-    /* tv_sec overflow check on Windows there we know it is long */
-    if(tv_sec > LONG_MAX)
-      tv_sec = LONG_MAX;
-#endif
-    pending_tv.tv_sec = (long)tv_sec;
-    pending_tv.tv_usec = (long)tv_usec;
-#else
-#if TIMEDIFF_T_MAX > INT_MAX
-    /* tv_sec overflow check in case time_t is signed */
-    if(tv_sec > INT_MAX)
-      tv_sec = INT_MAX;
-#endif
-    pending_tv.tv_sec = (int)tv_sec;
-    pending_tv.tv_usec = (int)tv_usec;
-#endif
-  }
-  else {
-    pending_tv.tv_sec = 0;
-    pending_tv.tv_usec = 0;
-  }
+  ptimeout = curlx_mstotv(&pending_tv, timeout_ms);
 
 #ifdef USE_WINSOCK
   /* WinSock select() must not be called with an fd_set that contains zero
diff --git a/lib/timediff.c b/lib/timediff.c
new file mode 100644 (file)
index 0000000..003477c
--- /dev/null
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timediff.h"
+
+/*
+ * Converts number of milliseconds into a timeval structure.
+ *
+ * Return values:
+ *    NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select)
+ *    tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select)
+ *    tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select)
+ */
+struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms)
+{
+  if(!tv)
+    return NULL;
+
+  if(ms < 0)
+    return NULL;
+
+  if(ms > 0) {
+    timediff_t tv_sec = ms / 1000;
+    timediff_t tv_usec = (ms % 1000) * 1000; /* max=999999 */
+#ifdef HAVE_SUSECONDS_T
+#if TIMEDIFF_T_MAX > TIME_T_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > TIME_T_MAX)
+      tv_sec = TIME_T_MAX;
+#endif
+    tv->tv_sec = (time_t)tv_sec;
+    tv->tv_usec = (suseconds_t)tv_usec;
+#elif defined(WIN32) /* maybe also others in the future */
+#if TIMEDIFF_T_MAX > LONG_MAX
+    /* tv_sec overflow check on Windows there we know it is long */
+    if(tv_sec > LONG_MAX)
+      tv_sec = LONG_MAX;
+#endif
+    tv->tv_sec = (long)tv_sec;
+    tv->tv_usec = (long)tv_usec;
+#else
+#if TIMEDIFF_T_MAX > INT_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > INT_MAX)
+      tv_sec = INT_MAX;
+#endif
+    tv->tv_sec = (int)tv_sec;
+    tv->tv_usec = (int)tv_usec;
+#endif
+  }
+  else {
+    tv->tv_sec = 0;
+    tv->tv_usec = 0;
+  }
+
+  return tv;
+}
+
+/*
+ * Converts a timeval structure into number of milliseconds.
+ */
+timediff_t curlx_tvtoms(struct timeval *tv)
+{
+  return (tv->tv_sec*1000) + (timediff_t)(((double)tv->tv_usec)/1000.0);
+}
diff --git a/lib/timediff.h b/lib/timediff.h
new file mode 100644 (file)
index 0000000..fcd5f05
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef HEADER_CURL_TIMEDIFF_H
+#define HEADER_CURL_TIMEDIFF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/* Use a larger type even for 32 bit time_t systems so that we can keep
+   microsecond accuracy in it */
+typedef curl_off_t timediff_t;
+#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
+
+#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
+#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
+
+/*
+ * Converts number of milliseconds into a timeval structure.
+ *
+ * Return values:
+ *    NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select)
+ *    tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select)
+ *    tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select)
+ */
+struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms);
+
+/*
+ * Converts a timeval structure into number of milliseconds.
+ */
+timediff_t curlx_tvtoms(struct timeval *tv);
+
+#endif /* HEADER_CURL_TIMEDIFF_H */
index 685e72961d19bdb3887765469d3492305612cff2..7c60ce205fd6577f59775584344e5e21980baa57 100644 (file)
 
 #include "curl_setup.h"
 
-/* Use a larger type even for 32 bit time_t systems so that we can keep
-   microsecond accuracy in it */
-typedef curl_off_t timediff_t;
-#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
-
-#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
-#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
+#include "timediff.h"
 
 struct curltime {
   time_t tv_sec; /* seconds */
index 9fcbfb734d04e0bdd9fce3503a40648a9ffcff44..9b5fbe4dd628f1332e6190d6b2cf5687cdd06340 100644 (file)
@@ -74,6 +74,7 @@
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
 #include "strcase.h"
+#include "timediff.h"
 #include "x509asn1.h"
 #include "curl_printf.h"
 
@@ -975,11 +976,12 @@ static CURLcode gskit_connect_step2(struct Curl_easy *data,
 
   for(;;) {
     timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+    stmv.tv_sec = 0;
+    stmv.tv_usec = 0;
     if(timeout_ms < 0)
       timeout_ms = 0;
-    stmv.tv_sec = timeout_ms / 1000;
-    stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
-    switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, &stmv)) {
+    switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat,
+                                  curlx_mstotv(&stmv, timeout_ms))) {
     case 1:             /* Operation complete. */
       break;
     case -1:            /* An error occurred: handshake still in progress. */
index 85e460f0d4e45f8e70f52a6e34395320485eb851..71c736fa5df0a27f6044073500dd10fcfa4227ad 100644 (file)
@@ -209,6 +209,7 @@ rem
       for /f "delims=" %%r in ('dir /b ..\src\*.rc') do call :element %1 src "%%r" %3
     ) else if "!var!" == "CURL_SRC_X_C_FILES" (
       call :element %1 lib "strtoofft.c" %3
+      call :element %1 lib "timediff.c" %3
       call :element %1 lib "nonblock.c" %3
       call :element %1 lib "warnless.c" %3
       call :element %1 lib "curl_ctype.c" %3
@@ -219,6 +220,7 @@ rem
       call :element %1 lib "config-win32.h" %3
       call :element %1 lib "curl_setup.h" %3
       call :element %1 lib "strtoofft.h" %3
+      call :element %1 lib "timediff.h" %3
       call :element %1 lib "nonblock.h" %3
       call :element %1 lib "warnless.h" %3
       call :element %1 lib "curl_ctype.h" %3
index 7761ba50035aa7ae7113affc08baf0d536b72d31..265b4d7a1173b851181acc0ed05b4039d882f154 100644 (file)
@@ -31,6 +31,7 @@
 # the official API, but we re-use the code here to avoid duplication.
 CURLX_CFILES = \
   ../lib/strtoofft.c \
+  ../lib/timediff.c \
   ../lib/nonblock.c \
   ../lib/warnless.c \
   ../lib/curl_ctype.c \
@@ -41,6 +42,7 @@ CURLX_CFILES = \
 CURLX_HFILES = \
   ../lib/curl_setup.h \
   ../lib/strtoofft.h \
+  ../lib/timediff.h \
   ../lib/nonblock.h \
   ../lib/warnless.h \
   ../lib/curl_ctype.h \
index a8739073345f5ef63cc301fb68ae18793fbcc5c7..c12f9689b4ccdaea24973dc9c70d471febcdcff7 100644 (file)
@@ -32,7 +32,7 @@ WARNLESS = ../../lib/warnless.c ../../lib/warnless.h
 MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h
 
 # these files are used in every single test program below
-SUPPORTFILES = first.c test.h
+SUPPORTFILES = ../../lib/timediff.c ../../lib/timediff.h first.c test.h
 
 # These are all libcurl test programs
 noinst_PROGRAMS = chkhostname libauthretry libntlmconnect                \
index 4ba0fab60bdbfe40090051b7de8272dce56083ba..a21f9485aca04fb7a1f9f51c7080df59d2fd4fad 100644 (file)
@@ -42,6 +42,8 @@
 #  include "memdebug.h"
 #endif
 
+#include "timediff.h"
+
 int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
                    struct timeval *tv)
 {
@@ -56,7 +58,7 @@ int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
    * select() can not be used to sleep without a single fd_set.
    */
   if(!nfds) {
-    Sleep((1000*tv->tv_sec) + (DWORD)(((double)tv->tv_usec)/1000.0));
+    Sleep((DWORD)curlx_tvtoms(tv));
     return 0;
   }
 #endif
@@ -65,11 +67,13 @@ int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
 
 void wait_ms(int ms)
 {
+#ifdef USE_WINSOCK
+  Sleep(ms);
+#else
   struct timeval t;
-  t.tv_sec = ms/1000;
-  ms -= (int)t.tv_sec * 1000;
-  t.tv_usec = ms * 1000;
+  curlx_mstotv(&t, ms);
   select_wrapper(0, NULL, NULL, NULL, &t);
+#endif
 }
 
 char *libtest_arg2 = NULL;
index dd83fc021895401f5738c60176113c9769cd6340..57a922c3ab613fb7d82eabfe96febdc1d74e7522 100644 (file)
@@ -22,6 +22,7 @@
 #include "test.h"
 
 #include "testutil.h"
+#include "timediff.h"
 #include "warnless.h"
 #include "memdebug.h"
 
@@ -102,11 +103,11 @@ int test(char *URL)
 
     curl_multi_timeout(mcurl, &curl_timeo);
     if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
+      curlx_mstotv(&timeout, curl_timeo);
+      if(timeout.tv_sec > 1) {
         timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
+        timeout.tv_usec = 0;
+      }
     }
 
     /* get file descriptors from the transfers */
index 6d7ea6aa903c7e479203b51db5778bc126bbcec7..4de0c374eab2c9337c1b64ca2ecfaca4e01fde1b 100644 (file)
@@ -22,6 +22,7 @@
 #include "test.h"
 
 #include "testutil.h"
+#include "timediff.h"
 #include "warnless.h"
 #include "memdebug.h"
 
@@ -85,11 +86,11 @@ int test(char *URL)
 
     curl_multi_timeout(multi_handle, &curl_timeo);
     if(curl_timeo >= 0) {
-      timeout.tv_sec = curl_timeo / 1000;
-      if(timeout.tv_sec > 1)
+      curlx_mstotv(&timeout, curl_timeo);
+      if(timeout.tv_sec > 1) {
         timeout.tv_sec = 1;
-      else
-        timeout.tv_usec = (curl_timeo % 1000) * 1000;
+        timeout.tv_usec = 0;
+      }
     }
 
     /* get file descriptors from the transfers */
index bc1acf84649addabdae3cb75a5b25999c342da91..c9d2c5868b4357d973210645fce112a42de88429 100644 (file)
@@ -22,6 +22,7 @@
 #include "test.h"
 
 #include "testutil.h"
+#include "timediff.h"
 #include "warnless.h"
 #include "memdebug.h"
 
@@ -73,8 +74,7 @@ int test(char *URL)
     curl_multi_timeout(cm, &max_tout);
 
     if(max_tout > 0) {
-      timeout.tv_sec = max_tout / 1000;
-      timeout.tv_usec = (max_tout % 1000) * 1000;
+      curlx_mstotv(&timeout, max_tout);
     }
     else {
       timeout.tv_sec = 0;
index 35d4dbaa1ac43bc48253987e0d8c1d692ab35684..195496089a4b1211f2c88d0e49f5bc3556372c9e 100644 (file)
@@ -28,6 +28,7 @@ CURLX_SRCS = \
  ../../lib/nonblock.c \
  ../../lib/strtoofft.c \
  ../../lib/warnless.c \
+ ../../lib/timediff.c \
  ../../lib/curl_ctype.c \
  ../../lib/dynbuf.c \
  ../../lib/strdup.c \
@@ -38,6 +39,7 @@ CURLX_HDRS = \
  ../../lib/nonblock.h \
  ../../lib/strtoofft.h \
  ../../lib/warnless.h \
+ ../../lib/timediff.h \
  ../../lib/curl_ctype.h \
  ../../lib/dynbuf.h \
  ../../lib/strdup.h \
index ccd9c4782814bf463813afe32bdc6d03e0309607..0af5165801d2a4d5764ceb8175b9d58be3be1876 100644 (file)
 #include "inet_pton.h"
 #include "util.h"
 #include "server_sockaddr.h"
+#include "timediff.h"
 #include "warnless.h"
 
 /* include memdebug.h last */
@@ -639,7 +640,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
 
   /* convert struct timeval to milliseconds */
   if(tv) {
-    timeout_ms = (tv->tv_sec*1000) + (DWORD)(((double)tv->tv_usec)/1000.0);
+    timeout_ms = (DWORD)curlx_tvtoms(tv);
   }
   else {
     timeout_ms = INFINITE;