diff options
-rw-r--r-- | lib/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/asyn-ares.c | 3 | ||||
-rw-r--r-- | lib/select.c | 61 | ||||
-rw-r--r-- | lib/timediff.c | 84 | ||||
-rw-r--r-- | lib/timediff.h | 50 | ||||
-rw-r--r-- | lib/timeval.h | 8 | ||||
-rw-r--r-- | lib/vtls/gskit.c | 8 | ||||
-rw-r--r-- | projects/generate.bat | 2 | ||||
-rw-r--r-- | src/Makefile.inc | 2 | ||||
-rw-r--r-- | tests/libtest/Makefile.inc | 2 | ||||
-rw-r--r-- | tests/libtest/first.c | 12 | ||||
-rw-r--r-- | tests/libtest/lib1507.c | 9 | ||||
-rw-r--r-- | tests/libtest/lib1531.c | 9 | ||||
-rw-r--r-- | tests/libtest/lib1905.c | 4 | ||||
-rw-r--r-- | tests/server/Makefile.inc | 2 | ||||
-rw-r--r-- | tests/server/sockfilt.c | 3 |
16 files changed, 176 insertions, 85 deletions
diff --git a/lib/Makefile.inc b/lib/Makefile.inc index cfd56d719..1ab007896 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -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 \ diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index fd0bb6c96..5857b99e4 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -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); diff --git a/lib/select.c b/lib/select.c index 1de207725..a48da82ba 100644 --- a/lib/select.c +++ b/lib/select.c @@ -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 index 000000000..003477c63 --- /dev/null +++ b/lib/timediff.c @@ -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 index 000000000..fcd5f0563 --- /dev/null +++ b/lib/timediff.h @@ -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 */ diff --git a/lib/timeval.h b/lib/timeval.h index 685e72961..7c60ce205 100644 --- a/lib/timeval.h +++ b/lib/timeval.h @@ -24,13 +24,7 @@ #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 */ diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c index 9fcbfb734..9b5fbe4dd 100644 --- a/lib/vtls/gskit.c +++ b/lib/vtls/gskit.c @@ -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. */ diff --git a/projects/generate.bat b/projects/generate.bat index 85e460f0d..71c736fa5 100644 --- a/projects/generate.bat +++ b/projects/generate.bat @@ -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 diff --git a/src/Makefile.inc b/src/Makefile.inc index 7761ba500..265b4d7a1 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -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 \ diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index a87390733..c12f9689b 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -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 \ diff --git a/tests/libtest/first.c b/tests/libtest/first.c index 4ba0fab60..a21f9485a 100644 --- a/tests/libtest/first.c +++ b/tests/libtest/first.c @@ -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; diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c index dd83fc021..57a922c3a 100644 --- a/tests/libtest/lib1507.c +++ b/tests/libtest/lib1507.c @@ -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 */ diff --git a/tests/libtest/lib1531.c b/tests/libtest/lib1531.c index 6d7ea6aa9..4de0c374e 100644 --- a/tests/libtest/lib1531.c +++ b/tests/libtest/lib1531.c @@ -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 */ diff --git a/tests/libtest/lib1905.c b/tests/libtest/lib1905.c index bc1acf846..c9d2c5868 100644 --- a/tests/libtest/lib1905.c +++ b/tests/libtest/lib1905.c @@ -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; diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc index 35d4dbaa1..195496089 100644 --- a/tests/server/Makefile.inc +++ b/tests/server/Makefile.inc @@ -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 \ diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index ccd9c4782..0af516580 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -107,6 +107,7 @@ #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; |