diff --git a/meson.build b/meson.build index cd711c6d018..ea07126f78e 100644 --- a/meson.build +++ b/meson.build @@ -268,6 +268,10 @@ elif host_system == 'windows' exesuffix = '.exe' dlsuffix = '.dll' library_path_var = '' + if cc.get_id() != 'msvc' + # define before including for getting localtime_r() etc. on MinGW + cppflags += '-D_POSIX_C_SOURCE' + endif export_file_format = 'win' export_file_suffix = 'def' diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 48b7e16d81b..643cca05d38 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -826,6 +826,7 @@ cache_locale_time(void) char *bufptr; time_t timenow; struct tm *timeinfo; + struct tm timeinfobuf; bool strftimefail = false; int encoding; int i; @@ -876,7 +877,7 @@ cache_locale_time(void) /* We use times close to current time as data for strftime(). */ timenow = time(NULL); - timeinfo = localtime(&timenow); + timeinfo = gmtime_r(&timenow, &timeinfobuf); /* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */ bufptr = buf; diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h index 7ffe5891c69..7789e0431aa 100644 --- a/src/include/port/win32_port.h +++ b/src/include/port/win32_port.h @@ -420,6 +420,19 @@ extern int _pglstat64(const char *name, struct stat *buf); */ #define strtok_r strtok_s +/* + * Supplement to . + */ +#ifdef _MSC_VER +/* + * MinGW has these functions if _POSIX_C_SOURCE is defined. Third-party + * libraries might do that, so to avoid clashes we get ahead of it and define + * it ourselves and use the system functions provided by MinGW. + */ +#define gmtime_r(clock, result) (gmtime_s(result, clock) ? NULL : (result)) +#define localtime_r(clock, result) (localtime_s(result, clock) ? NULL : (result)) +#endif + /* * Locale stuff. * diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c index ed08088bfe1..0d63fe52c5b 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt_common.c +++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c @@ -949,9 +949,10 @@ int GetEpochTime(struct tm *tm) { struct tm *t0; + struct tm tmbuf; time_t epoch = 0; - t0 = gmtime(&epoch); + t0 = gmtime_r(&epoch, &tmbuf); if (t0) { @@ -973,12 +974,13 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn) { time_t time = (time_t) _time; struct tm *tx; + struct tm tmbuf; errno = 0; if (tzp != NULL) - tx = localtime((time_t *) &time); + tx = localtime_r(&time, &tmbuf); else - tx = gmtime((time_t *) &time); + tx = gmtime_r(&time, &tmbuf); if (!tx) { @@ -2810,9 +2812,10 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d, /* number of seconds in scan_val.luint_val */ { struct tm *tms; + struct tm tmbuf; time_t et = (time_t) scan_val.luint_val; - tms = gmtime(&et); + tms = gmtime_r(&et, &tmbuf); if (tms) { diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c index 402fae6da67..7cf433266f4 100644 --- a/src/interfaces/ecpg/pgtypeslib/timestamp.c +++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c @@ -129,11 +129,12 @@ timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, const char **t if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) { #if defined(HAVE_STRUCT_TM_TM_ZONE) || defined(HAVE_INT_TIMEZONE) + struct tm tmbuf; utime = dt / USECS_PER_SEC + ((date0 - date2j(1970, 1, 1)) * INT64CONST(86400)); - tx = localtime(&utime); + tx = localtime_r(&utime, &tmbuf); tm->tm_year = tx->tm_year + 1900; tm->tm_mon = tx->tm_mon + 1; tm->tm_mday = tx->tm_mday; diff --git a/src/interfaces/libpq/fe-trace.c b/src/interfaces/libpq/fe-trace.c index bff7d919d57..19c5b8a8900 100644 --- a/src/interfaces/libpq/fe-trace.c +++ b/src/interfaces/libpq/fe-trace.c @@ -81,6 +81,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len) { struct timeval tval; time_t now; + struct tm tmbuf; gettimeofday(&tval, NULL); @@ -93,7 +94,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len) now = tval.tv_sec; strftime(timestr, ts_len, "%Y-%m-%d %H:%M:%S", - localtime(&now)); + localtime_r(&now, &tmbuf)); /* append microseconds */ snprintf(timestr + strlen(timestr), ts_len - strlen(timestr), ".%06u", (unsigned int) (tval.tv_usec)); diff --git a/src/template/win32 b/src/template/win32 index 1895f067a88..4f8b0923fe0 100644 --- a/src/template/win32 +++ b/src/template/win32 @@ -1,5 +1,8 @@ # src/template/win32 +# define before including for getting localtime_r() etc. on MinGW +CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE" + # Extra CFLAGS for code that will go into a shared library CFLAGS_SL=""