diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2024-08-23 07:07:53 +0200 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2024-08-23 07:43:04 +0200 |
commit | a2bbc58f743489784de797d81be37ea309cb0773 (patch) | |
tree | c5d9ddf99403cfd2feee359f4497ba11ffae9f8d /src/backend/utils/adt/pg_locale.c | |
parent | 94a3373ac5c3d2444b2379a3c185b986627c42d4 (diff) | |
download | postgresql-a2bbc58f743489784de797d81be37ea309cb0773.tar.gz postgresql-a2bbc58f743489784de797d81be37ea309cb0773.zip |
thread-safety: gmtime_r(), localtime_r()
Use gmtime_r() and localtime_r() instead of gmtime() and localtime(),
for thread-safety.
There are a few affected calls in libpq and ecpg's libpgtypes, which
are probably effectively bugs, because those libraries already claim
to be thread-safe.
There is one affected call in the backend. Most of the backend
otherwise uses the custom functions pg_gmtime() and pg_localtime(),
which are implemented differently.
While we're here, change the call in the backend to gmtime*() instead
of localtime*(), since for that use time zone behavior is irrelevant,
and this side-steps any questions about when time zones are
initialized by localtime_r() vs localtime().
Portability: gmtime_r() and localtime_r() are in POSIX but are not
available on Windows. Windows has functions gmtime_s() and
localtime_s() that can fulfill the same purpose, so we add some small
wrappers around them. (Note that these *_s() functions are also
different from the *_s() functions in the bounds-checking extension of
C11. We are not using those here.)
On MinGW, you can get the POSIX-style *_r() functions by defining
_POSIX_C_SOURCE appropriately before including <time.h>. This leads
to a conflict at least in plpython because apparently _POSIX_C_SOURCE
gets defined in some header there, and then our replacement
definitions conflict with the system definitions. To avoid that sort
of thing, we now always define _POSIX_C_SOURCE on MinGW and use the
POSIX-style functions here.
Reviewed-by: Stepan Neretin <sncfmgg@gmail.com>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/eba1dc75-298e-4c46-8869-48ba8aad7d70@eisentraut.org
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r-- | src/backend/utils/adt/pg_locale.c | 3 |
1 files changed, 2 insertions, 1 deletions
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; |