localtime: detect thread-safe alternatives and use them
No binary (build failed)
—
(log yok)
| @@ -169,6 +169,7 @@ else() | |
| set(HAVE_LINUX_TCP_H 0) | |
| endif() | |
| set(HAVE_LOCALE_H 1) | |
| + | set(HAVE_LOCALTIME_R 1) |
| set(HAVE_LONGLONG 1) | |
| if(APPLE) | |
| set(HAVE_MACH_ABSOLUTE_TIME 1) | |
| @@ -123,6 +123,7 @@ set(HAVE_IOCTL_SIOCGIFADDR 0) | |
| set(HAVE_IO_H 1) | |
| set(HAVE_LINUX_TCP_H 0) | |
| set(HAVE_LOCALE_H 1) | |
| + | set(HAVE_LOCALTIME_R 0) |
| set(HAVE_MEMRCHR 0) | |
| set(HAVE_MSG_NOSIGNAL 0) | |
| set(HAVE_NETDB_H 0) | |
| @@ -1570,6 +1570,7 @@ check_function_exists("getpwuid_r" HAVE_GETPWUID_R) | |
| check_function_exists("geteuid" HAVE_GETEUID) | |
| check_function_exists("utime" HAVE_UTIME) | |
| check_symbol_exists("gmtime_r" "stdlib.h;time.h" HAVE_GMTIME_R) | |
| + | check_symbol_exists("localtime_r" "stdlib.h;time.h" HAVE_LOCALTIME_R) |
| check_symbol_exists("gethostbyname_r" "netdb.h" HAVE_GETHOSTBYNAME_R) | |
| check_symbol_exists("gethostname" "${CURL_INCLUDES}" HAVE_GETHOSTNAME) # winsock2.h unistd.h proto/bsdsocket.h | |
| @@ -4203,6 +4203,7 @@ CURL_CHECK_FUNC_GMTIME_R | |
| CURL_CHECK_FUNC_IOCTL | |
| CURL_CHECK_FUNC_IOCTLSOCKET | |
| CURL_CHECK_FUNC_IOCTLSOCKET_CAMEL | |
| + | CURL_CHECK_FUNC_LOCALTIME_R |
| CURL_CHECK_FUNC_MEMRCHR | |
| CURL_CHECK_FUNC_SIGACTION | |
| CURL_CHECK_FUNC_SIGINTERRUPT | |
| @@ -108,6 +108,9 @@ | |
| /* Define if you have the GNU gssapi libraries */ | |
| #undef HAVE_GSSGNU | |
| + | /* Define if you have the `localtime_r' function. */ |
| + | #define HAVE_LOCALTIME_R |
| + | |
| /* Define if you have the <netdb.h> header file. */ | |
| #define HAVE_NETDB_H | |
| @@ -86,6 +86,7 @@ | |
| #define HAVE_LIBGEN_H 1 | |
| #define HAVE_LIBZ 1 | |
| #define HAVE_LOCALE_H 1 | |
| + | #define HAVE_LOCALTIME_R 1 |
| #define HAVE_LONGLONG 1 | |
| #define HAVE_NETDB_H 1 | |
| #define HAVE_NETINET_IN_H 1 | |
| @@ -391,6 +391,9 @@ | |
| /* Define to 1 if you have the <locale.h> header file. */ | |
| #cmakedefine HAVE_LOCALE_H 1 | |
| + | /* Define to 1 if you have a working localtime_r function. */ |
| + | #cmakedefine HAVE_LOCALTIME_R 1 |
| + | |
| /* Define to 1 if the compiler supports the 'long long' data type. */ | |
| #cmakedefine HAVE_LONGLONG 1 | |
| @@ -94,8 +94,7 @@ | |
| #define _CRT_NONSTDC_NO_DEPRECATE /* for close(), fileno(), unlink(), etc. */ | |
| #endif | |
| #ifndef _CRT_SECURE_NO_WARNINGS | |
| - | #define _CRT_SECURE_NO_WARNINGS /* for getenv(), strcpy(), |
| - | in tests: localtime(), sscanf() */ |
| + | #define _CRT_SECURE_NO_WARNINGS /* for getenv(), strcpy(), tests: sscanf() */ |
| #endif | |
| #endif /* _MSC_VER */ | |
| @@ -2204,6 +2204,126 @@ AC_DEFUN([CURL_CHECK_FUNC_GMTIME_R], [ | |
| ]) | |
| + | dnl CURL_CHECK_FUNC_LOCALTIME_R |
| + | dnl ------------------------------------------------- |
| + | dnl Verify if localtime_r is available, prototyped, can |
| + | dnl be compiled and seems to work. If all of these are |
| + | dnl true, and usage has not been previously disallowed |
| + | dnl with shell variable curl_disallow_localtime_r, then |
| + | dnl HAVE_LOCALTIME_R will be defined. |
| + | |
| + | AC_DEFUN([CURL_CHECK_FUNC_LOCALTIME_R], [ |
| + | AC_REQUIRE([CURL_INCLUDES_STDLIB])dnl |
| + | AC_REQUIRE([CURL_INCLUDES_TIME])dnl |
| + | # |
| + | tst_links_localtime_r="unknown" |
| + | tst_proto_localtime_r="unknown" |
| + | tst_compi_localtime_r="unknown" |
| + | tst_works_localtime_r="unknown" |
| + | tst_allow_localtime_r="unknown" |
| + | # |
| + | AC_MSG_CHECKING([if localtime_r can be linked]) |
| + | AC_LINK_IFELSE([ |
| + | AC_LANG_FUNC_LINK_TRY([localtime_r]) |
| + | ],[ |
| + | AC_MSG_RESULT([yes]) |
| + | tst_links_localtime_r="yes" |
| + | ],[ |
| + | AC_MSG_RESULT([no]) |
| + | tst_links_localtime_r="no" |
| + | ]) |
| + | # |
| + | if test "$tst_links_localtime_r" = "yes"; then |
| + | AC_MSG_CHECKING([if localtime_r is prototyped]) |
| + | AC_EGREP_CPP([localtime_r],[ |
| + | $curl_includes_time |
| + | ],[ |
| + | AC_MSG_RESULT([yes]) |
| + | tst_proto_localtime_r="yes" |
| + | ],[ |
| + | AC_MSG_RESULT([no]) |
| + | tst_proto_localtime_r="no" |
| + | ]) |
| + | fi |
| + | # |
| + | if test "$tst_proto_localtime_r" = "yes"; then |
| + | AC_MSG_CHECKING([if localtime_r is compilable]) |
| + | AC_COMPILE_IFELSE([ |
| + | AC_LANG_PROGRAM([[ |
| + | $curl_includes_time |
| + | ]],[[ |
| + | time_t clock = 1170352587; |
| + | struct tm result; |
| + | if(localtime_r(&clock, &result) != 0) |
| + | return 1; |
| + | (void)result; |
| + | ]]) |
| + | ],[ |
| + | AC_MSG_RESULT([yes]) |
| + | tst_compi_localtime_r="yes" |
| + | ],[ |
| + | AC_MSG_RESULT([no]) |
| + | tst_compi_localtime_r="no" |
| + | ]) |
| + | fi |
| + | # |
| + | dnl only do runtime verification when not cross-compiling |
| + | if test "$cross_compiling" != "yes" && |
| + | test "$tst_compi_localtime_r" = "yes"; then |
| + | AC_MSG_CHECKING([if localtime_r seems to work]) |
| + | CURL_RUN_IFELSE([ |
| + | AC_LANG_PROGRAM([[ |
| + | $curl_includes_stdlib |
| + | $curl_includes_time |
| + | ]],[[ |
| + | time_t clock = 1170352587; |
| + | struct tm *tmp = 0; |
| + | struct tm result; |
| + | tmp = localtime_r(&clock, &result); |
| + | (void)result; |
| + | if(tmp) |
| + | return 0; |
| + | else |
| + | return 1; |
| + | ]]) |
| + | ],[ |
| + | AC_MSG_RESULT([yes]) |
| + | tst_works_localtime_r="yes" |
| + | ],[ |
| + | AC_MSG_RESULT([no]) |
| + | tst_works_localtime_r="no" |
| + | ]) |
| + | fi |
| + | # |
| + | if test "$tst_compi_localtime_r" = "yes" && |
| + | test "$tst_works_localtime_r" != "no"; then |
| + | AC_MSG_CHECKING([if localtime_r usage allowed]) |
| + | if test "x$curl_disallow_localtime_r" != "xyes"; then |
| + | AC_MSG_RESULT([yes]) |
| + | tst_allow_localtime_r="yes" |
| + | else |
| + | AC_MSG_RESULT([no]) |
| + | tst_allow_localtime_r="no" |
| + | fi |
| + | fi |
| + | # |
| + | AC_MSG_CHECKING([if localtime_r might be used]) |
| + | if test "$tst_links_localtime_r" = "yes" && |
| + | test "$tst_proto_localtime_r" = "yes" && |
| + | test "$tst_compi_localtime_r" = "yes" && |
| + | test "$tst_allow_localtime_r" = "yes" && |
| + | test "$tst_works_localtime_r" != "no"; then |
| + | AC_MSG_RESULT([yes]) |
| + | AC_DEFINE_UNQUOTED(HAVE_LOCALTIME_R, 1, |
| + | [Define to 1 if you have a working localtime_r function.]) |
| + | curl_cv_func_localtime_r="yes" |
| + | else |
| + | AC_MSG_RESULT([no]) |
| + | curl_cv_func_localtime_r="no" |
| + | fi |
| + | ]) |
| + | |
| + | |
| dnl CURL_CHECK_FUNC_INET_NTOP | |
| dnl ------------------------------------------------- | |
| dnl Verify if inet_ntop is available, prototyped, can | |
| @@ -2296,10 +2296,12 @@ | |
| </ItemDefinitionGroup> | |
| <ItemGroup> | |
| CURL_LIB_CURLX_C_FILES | |
| + | CURL_SRC_TOOLX_C_FILES |
| CURL_SRC_C_FILES | |
| </ItemGroup> | |
| <ItemGroup> | |
| CURL_LIB_CURLX_H_FILES | |
| + | CURL_SRC_TOOLX_H_FILES |
| CURL_SRC_X_H_FILES | |
| CURL_SRC_H_FILES | |
| </ItemGroup> | |
| @@ -226,6 +226,10 @@ rem | |
| for /f "delims=" %%c in ('dir /b ..\lib\vtls\*.c') do call :element lib\vtls "%%c" %3 | |
| ) else if "!var!" == "CURL_LIB_VTLS_H_FILES" ( | |
| for /f "delims=" %%h in ('dir /b ..\lib\vtls\*.h') do call :element lib\vtls "%%h" %3 | |
| + | ) else if "!var!" == "CURL_SRC_TOOLX_C_FILES" ( |
| + | for /f "delims=" %%c in ('dir /b ..\src\toolx\*.c') do call :element src\toolx "%%c" %3 |
| + | ) else if "!var!" == "CURL_SRC_TOOLX_H_FILES" ( |
| + | for /f "delims=" %%h in ('dir /b ..\src\toolx\*.h') do call :element src\toolx "%%h" %3 |
| ) else ( | |
| echo.!var!>> %3 | |
| ) | |
| @@ -64,6 +64,12 @@ CURLX_HFILES = \ | |
| ../lib/curlx/warnless.h \ | |
| ../lib/curlx/winapi.h | |
| + | TOOLX_CFILES = \ |
| + | toolx/tool_time.c |
| + | |
| + | TOOLX_HFILES = \ |
| + | toolx/tool_time.h |
| + | |
| CURL_CFILES = \ | |
| config2setopts.c \ | |
| slist_wc.c \ | |
| @@ -107,7 +113,8 @@ CURL_CFILES = \ | |
| tool_writeout.c \ | |
| tool_writeout_json.c \ | |
| tool_xattr.c \ | |
| - | var.c |
| + | var.c \ |
| + | $(TOOLX_CFILES) |
| CURL_HFILES = \ | |
| config2setopts.h \ | |
| @@ -154,6 +161,7 @@ CURL_HFILES = \ | |
| tool_writeout.h \ | |
| tool_writeout_json.h \ | |
| tool_xattr.h \ | |
| - | var.h |
| + | var.h \ |
| + | $(TOOLX_HFILES) |
| CURL_RCFILES = curl.rc | |
| @@ -27,6 +27,7 @@ | |
| #include "tool_msgs.h" | |
| #include "tool_cb_dbg.h" | |
| #include "tool_util.h" | |
| + | #include "toolx/tool_time.h" |
| static void dump(const char *timebuf, const char *idsbuf, const char *text, | |
| FILE *stream, const unsigned char *ptr, size_t size, | |
| @@ -34,7 +35,6 @@ static void dump(const char *timebuf, const char *idsbuf, const char *text, | |
| /* | |
| * Return the formatted HH:MM:SS for the tv_sec given. | |
| - | * NOT thread safe. |
| */ | |
| static const char *hms_for_sec(time_t tv_sec) | |
| { | |
| @@ -42,10 +42,12 @@ static const char *hms_for_sec(time_t tv_sec) | |
| static char hms_buf[12]; | |
| if(tv_sec != cached_tv_sec) { | |
| - | /* !checksrc! disable BANNEDFUNC 1 */ |
| - | struct tm *now = localtime(&tv_sec); /* not thread safe either */ |
| + | struct tm now; |
| + | CURLcode result = toolx_localtime(tv_sec, &now); |
| + | if(result) |
| + | memset(&now, 0, sizeof(now)); |
| curl_msnprintf(hms_buf, sizeof(hms_buf), "%02d:%02d:%02d", | |
| - | now->tm_hour, now->tm_min, now->tm_sec); |
| + | now.tm_hour, now.tm_min, now.tm_sec); |
| cached_tv_sec = tv_sec; | |
| } | |
| return hms_buf; | |
| @@ -0,0 +1,61 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, 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. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "tool_time.h" |
| + | |
| + | #if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 3) |
| + | #include <sec_api/time_s.h> /* for _localtime32_s(), _localtime64_s() */ |
| + | #ifdef _USE_32BIT_TIME_T |
| + | #define localtime_s _localtime32_s |
| + | #else |
| + | #define localtime_s _localtime64_s |
| + | #endif |
| + | #endif |
| + | |
| + | /* |
| + | * toolx_localtime() is a localtime() replacement for portability. Do not use |
| + | * the localtime_s(), localtime_r() or localtime() functions anywhere else but |
| + | * here. |
| + | */ |
| + | CURLcode toolx_localtime(time_t intime, struct tm *store) |
| + | { |
| + | #ifdef _WIN32 |
| + | if(localtime_s(store, &intime)) /* thread-safe */ |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| + | #elif defined(HAVE_LOCALTIME_R) |
| + | const struct tm *tm; |
| + | tm = localtime_r(&intime, store); /* thread-safe */ |
| + | if(!tm) |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| + | #else |
| + | const struct tm *tm; |
| + | /* !checksrc! disable BANNEDFUNC 1 */ |
| + | tm = localtime(&intime); /* not thread-safe */ |
| + | if(tm) |
| + | *store = *tm; /* copy the pointed struct to the local copy */ |
| + | else |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| + | #endif |
| + | |
| + | return CURLE_OK; |
| + | } |
| @@ -0,0 +1,30 @@ | |
| + | #ifndef HEADER_TOOLX_TOOL_TIME_H |
| + | #define HEADER_TOOLX_TOOL_TIME_H |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, 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. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "curl_setup.h" |
| + | |
| + | CURLcode toolx_localtime(time_t intime, struct tm *store); |
| + | |
| + | #endif /* HEADER_TOOLX_TOOL_TIME_H */ |
| @@ -22,7 +22,7 @@ | |
| # | |
| ########################################################################### | |
| - | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TESTS_C variables |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") | |
| include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") | |
| @@ -41,10 +41,10 @@ list(APPEND TESTS_C "lib1521.c") | |
| add_custom_command(OUTPUT "${BUNDLE}.c" | |
| COMMAND ${PERL_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" | |
| - | --include ${UTILS_C} ${CURLX_C} --test ${TESTS_C} > "${BUNDLE}.c" |
| + | --include ${UTILS_C} ${CURLX_C} ${TOOLX_C} --test ${TESTS_C} > "${BUNDLE}.c" |
| DEPENDS | |
| "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.inc" | |
| - | ${FIRST_C} ${UTILS_C} ${CURLX_C} ${TESTS_C} |
| + | ${FIRST_C} ${UTILS_C} ${CURLX_C} ${TOOLX_C} ${TESTS_C} |
| VERBATIM) | |
| add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") | |
| @@ -53,6 +53,7 @@ target_link_libraries(${BUNDLE} ${LIB_SELECTED} ${CURL_LIBS}) | |
| target_include_directories(${BUNDLE} PRIVATE | |
| "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" | |
| "${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h", curlx | |
| + | "${PROJECT_SOURCE_DIR}/src" # for toolx |
| "${CMAKE_CURRENT_SOURCE_DIR}" # for the generated bundle source to find included test sources | |
| ) | |
| target_compile_definitions(${BUNDLE} PRIVATE ${CURL_DEBUG_MACROS}) | |
| @@ -31,14 +31,16 @@ AUTOMAKE_OPTIONS = foreign nostdinc | |
| # $(top_srcdir)/include is for libcurl's external include files | |
| # $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file | |
| # $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files | |
| + | # $(top_srcdir)/src for toolx header files |
| # $(srcdir) for the generated bundle source to find included test sources | |
| AM_CPPFLAGS = -I$(top_srcdir)/include \ | |
| -I$(top_builddir)/lib \ | |
| -I$(top_srcdir)/lib \ | |
| + | -I$(top_srcdir)/src \ |
| -I$(srcdir) | |
| - | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TESTS_C variables |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| include Makefile.inc | |
| EXTRA_DIST = CMakeLists.txt $(FIRST_C) $(FIRST_H) $(UTILS_C) $(UTILS_H) $(TESTS_C) \ | |
| @@ -65,8 +67,8 @@ else | |
| # These are part of the libcurl static lib. Add them here when linking shared. | |
| curlx_c_lib = $(CURLX_C) | |
| endif | |
| - | $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(curlx_c_lib) $(TESTS_C) lib1521.c |
| - | @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(curlx_c_lib) --test $(TESTS_C) lib1521.c > $(BUNDLE).c |
| + | $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) $(TESTS_C) lib1521.c |
| + | @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(curlx_c_lib) $(TOOLX_C) --test $(TESTS_C) lib1521.c > $(BUNDLE).c |
| noinst_PROGRAMS = $(BUNDLE) | |
| LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_PC_LIBS_PRIVATE@ | |
| @@ -46,6 +46,9 @@ CURLX_C = \ | |
| ../../lib/curlx/warnless.c \ | |
| ../../lib/curlx/winapi.c | |
| + | TOOLX_C = \ |
| + | ../../src/toolx/tool_time.c |
| + | |
| # All libtest programs | |
| TESTS_C = \ | |
| cli_ftp_upload.c \ | |
| @@ -23,6 +23,8 @@ | |
| ***************************************************************************/ | |
| #include "testtrace.h" | |
| + | #include <toolx/tool_time.h> |
| + | |
| struct libtest_trace_cfg debug_config; | |
| static time_t epoch_offset; /* for test time tracing */ | |
| @@ -93,7 +95,8 @@ int libtest_debug_cb(CURL *curl, curl_infotype type, | |
| timestr = &timebuf[0]; | |
| if(trace_cfg->tracetime) { | |
| - | struct tm *now; |
| + | CURLcode result; |
| + | struct tm now; |
| struct curltime tv; | |
| time_t secs; | |
| tv = curlx_now(); | |
| @@ -102,10 +105,11 @@ int libtest_debug_cb(CURL *curl, curl_infotype type, | |
| known_offset = 1; | |
| } | |
| secs = epoch_offset + tv.tv_sec; | |
| - | /* !checksrc! disable BANNEDFUNC 1 */ |
| - | now = localtime(&secs); /* not thread safe but we do not care */ |
| + | result = toolx_localtime(secs, &now); |
| + | if(result) |
| + | memset(&now, 0, sizeof(now)); |
| curl_msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ", | |
| - | now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec); |
| + | now.tm_hour, now.tm_min, now.tm_sec, (long)tv.tv_usec); |
| } | |
| switch(type) { | |
| @@ -22,16 +22,16 @@ | |
| # | |
| ########################################################################### | |
| - | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TESTS_C variables |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") | |
| include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") | |
| add_custom_command(OUTPUT "${BUNDLE}.c" | |
| COMMAND ${PERL_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" | |
| - | --include ${UTILS_C} ${CURLX_C} --test ${TESTS_C} > "${BUNDLE}.c" |
| + | --include ${UTILS_C} ${CURLX_C} ${TOOLX_C} --test ${TESTS_C} > "${BUNDLE}.c" |
| DEPENDS | |
| "${PROJECT_SOURCE_DIR}/scripts/mk-unity.pl" "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.inc" | |
| - | ${FIRST_C} ${UTILS_C} ${CURLX_C} ${TESTS_C} |
| + | ${FIRST_C} ${UTILS_C} ${CURLX_C} ${TOOLX_C} ${TESTS_C} |
| VERBATIM) | |
| add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") | |
| @@ -40,6 +40,7 @@ target_link_libraries(${BUNDLE} ${CURL_NETWORK_AND_TIME_LIBS}) | |
| target_include_directories(${BUNDLE} PRIVATE | |
| "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" | |
| "${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h", curlx | |
| + | "${PROJECT_SOURCE_DIR}/src" # for toolx |
| "${CMAKE_CURRENT_SOURCE_DIR}" # for the generated bundle source to find included test sources | |
| ) | |
| set_target_properties(${BUNDLE} PROPERTIES OUTPUT_NAME "${BUNDLE}" PROJECT_LABEL "Test ${BUNDLE}" UNITY_BUILD OFF C_CLANG_TIDY "") | |
| @@ -31,14 +31,16 @@ AUTOMAKE_OPTIONS = foreign nostdinc | |
| # $(top_srcdir)/include is for libcurl's external include files | |
| # $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file | |
| # $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files | |
| + | # $(top_srcdir)/src for toolx header files |
| # $(srcdir) for the generated bundle source to find included test sources | |
| AM_CPPFLAGS = -I$(top_srcdir)/include \ | |
| -I$(top_builddir)/lib \ | |
| -I$(top_srcdir)/lib \ | |
| + | -I$(top_srcdir)/src \ |
| -I$(srcdir) | |
| - | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TESTS_C variables |
| + | # Get BUNDLE, FIRST_C, FIRST_H, UTILS_C, UTILS_H, CURLX_C, TOOLX_C, TESTS_C variables |
| include Makefile.inc | |
| EXTRA_DIST = CMakeLists.txt .checksrc $(FIRST_C) $(FIRST_H) $(UTILS_C) $(UTILS_H) $(TESTS_C) | |
| @@ -48,8 +50,8 @@ CFLAGS += @CURL_CFLAG_EXTRAS@ | |
| # Prevent LIBS from being used for all link targets | |
| LIBS = $(BLANK_AT_MAKETIME) | |
| - | $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(CURLX_C) $(TESTS_C) |
| - | @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(CURLX_C) --test $(TESTS_C) > $(BUNDLE).c |
| + | $(BUNDLE).c: $(top_srcdir)/scripts/mk-unity.pl Makefile.inc $(FIRST_C) $(UTILS_C) $(CURLX_C) $(TOOLX_C) $(TESTS_C) |
| + | @PERL@ $(top_srcdir)/scripts/mk-unity.pl --include $(UTILS_C) $(CURLX_C) $(TOOLX_C) --test $(TESTS_C) > $(BUNDLE).c |
| noinst_PROGRAMS = $(BUNDLE) | |
| LDADD = @CURL_NETWORK_AND_TIME_LIBS@ | |
| @@ -49,6 +49,9 @@ CURLX_C = \ | |
| ../../lib/curlx/warnless.c \ | |
| ../../lib/curlx/winapi.c | |
| + | TOOLX_C = \ |
| + | ../../src/toolx/tool_time.c |
| + | |
| # All test servers | |
| TESTS_C = \ | |
| dnsd.c \ | |
| @@ -23,6 +23,8 @@ | |
| ***************************************************************************/ | |
| #include "first.h" | |
| + | #include <toolx/tool_time.h> |
| + | |
| #ifdef HAVE_FCNTL_H | |
| #include <fcntl.h> | |
| #endif | |
| @@ -83,8 +85,9 @@ void logmsg(const char *msg, ...) | |
| char buffer[2048 + 1]; | |
| FILE *logfp; | |
| struct curltime tv; | |
| + | CURLcode result; |
| time_t sec; | |
| - | struct tm *now; |
| + | struct tm now; |
| char timebuf[50]; | |
| static time_t epoch_offset; | |
| static int known_offset; | |
| @@ -100,12 +103,12 @@ void logmsg(const char *msg, ...) | |
| known_offset = 1; | |
| } | |
| sec = epoch_offset + tv.tv_sec; | |
| - | /* !checksrc! disable BANNEDFUNC 1 */ |
| - | now = localtime(&sec); /* not thread safe but we do not care */ |
| + | result = toolx_localtime(sec, &now); |
| + | if(result) |
| + | memset(&now, 0, sizeof(now)); |
| snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld", | |
| - | (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, |
| - | (long)tv.tv_usec); |
| + | now.tm_hour, now.tm_min, now.tm_sec, (long)tv.tv_usec); |
| va_start(ap, msg); | |
| #ifdef __clang__ | |