Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita2bbc58

Browse files
committed
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, whichare probably effectively bugs, because those libraries already claimto be thread-safe.There is one affected call in the backend. Most of the backendotherwise 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*() insteadof localtime*(), since for that use time zone behavior is irrelevant,and this side-steps any questions about when time zones areinitialized by localtime_r() vs localtime().Portability: gmtime_r() and localtime_r() are in POSIX but are notavailable on Windows. Windows has functions gmtime_s() andlocaltime_s() that can fulfill the same purpose, so we add some smallwrappers around them. (Note that these *_s() functions are alsodifferent from the *_s() functions in the bounds-checking extension ofC11. 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 leadsto a conflict at least in plpython because apparently _POSIX_C_SOURCEgets defined in some header there, and then our replacementdefinitions conflict with the system definitions. To avoid that sortof thing, we now always define _POSIX_C_SOURCE on MinGW and use thePOSIX-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
1 parent94a3373 commita2bbc58

File tree

7 files changed

+33
-7
lines changed

7 files changed

+33
-7
lines changed

‎meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ elif host_system == 'windows'
268268
exesuffix='.exe'
269269
dlsuffix='.dll'
270270
library_path_var=''
271+
if cc.get_id()!='msvc'
272+
# define before including <time.h> for getting localtime_r() etc. on MinGW
273+
cppflags+='-D_POSIX_C_SOURCE'
274+
endif
271275

272276
export_file_format='win'
273277
export_file_suffix='def'

‎src/backend/utils/adt/pg_locale.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ cache_locale_time(void)
826826
char*bufptr;
827827
time_ttimenow;
828828
structtm*timeinfo;
829+
structtmtimeinfobuf;
829830
boolstrftimefail= false;
830831
intencoding;
831832
inti;
@@ -876,7 +877,7 @@ cache_locale_time(void)
876877

877878
/* We use times close to current time as data for strftime(). */
878879
timenow=time(NULL);
879-
timeinfo=localtime(&timenow);
880+
timeinfo=gmtime_r(&timenow,&timeinfobuf);
880881

881882
/* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */
882883
bufptr=buf;

‎src/include/port/win32_port.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,19 @@ extern int_pglstat64(const char *name, struct stat *buf);
420420
*/
421421
#definestrtok_r strtok_s
422422

423+
/*
424+
* Supplement to <time.h>.
425+
*/
426+
#ifdef_MSC_VER
427+
/*
428+
* MinGW has these functions if _POSIX_C_SOURCE is defined. Third-party
429+
* libraries might do that, so to avoid clashes we get ahead of it and define
430+
* it ourselves and use the system functions provided by MinGW.
431+
*/
432+
#definegmtime_r(clock,result) (gmtime_s(result, clock) ? NULL : (result))
433+
#definelocaltime_r(clock,result) (localtime_s(result, clock) ? NULL : (result))
434+
#endif
435+
423436
/*
424437
* Locale stuff.
425438
*

‎src/interfaces/ecpg/pgtypeslib/dt_common.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -949,9 +949,10 @@ int
949949
GetEpochTime(structtm*tm)
950950
{
951951
structtm*t0;
952+
structtmtmbuf;
952953
time_tepoch=0;
953954

954-
t0=gmtime(&epoch);
955+
t0=gmtime_r(&epoch,&tmbuf);
955956

956957
if (t0)
957958
{
@@ -973,12 +974,13 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
973974
{
974975
time_ttime= (time_t)_time;
975976
structtm*tx;
977+
structtmtmbuf;
976978

977979
errno=0;
978980
if (tzp!=NULL)
979-
tx=localtime((time_t*)&time);
981+
tx=localtime_r(&time,&tmbuf);
980982
else
981-
tx=gmtime((time_t*)&time);
983+
tx=gmtime_r(&time,&tmbuf);
982984

983985
if (!tx)
984986
{
@@ -2810,9 +2812,10 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
28102812
/* number of seconds in scan_val.luint_val */
28112813
{
28122814
structtm*tms;
2815+
structtmtmbuf;
28132816
time_tet= (time_t)scan_val.luint_val;
28142817

2815-
tms=gmtime(&et);
2818+
tms=gmtime_r(&et,&tmbuf);
28162819

28172820
if (tms)
28182821
{

‎src/interfaces/ecpg/pgtypeslib/timestamp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,12 @@ timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, const char **t
129129
if (IS_VALID_UTIME(tm->tm_year,tm->tm_mon,tm->tm_mday))
130130
{
131131
#if defined(HAVE_STRUCT_TM_TM_ZONE)|| defined(HAVE_INT_TIMEZONE)
132+
structtmtmbuf;
132133

133134
utime=dt /USECS_PER_SEC+
134135
((date0-date2j(1970,1,1))*INT64CONST(86400));
135136

136-
tx=localtime(&utime);
137+
tx=localtime_r(&utime,&tmbuf);
137138
tm->tm_year=tx->tm_year+1900;
138139
tm->tm_mon=tx->tm_mon+1;
139140
tm->tm_mday=tx->tm_mday;

‎src/interfaces/libpq/fe-trace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len)
8181
{
8282
structtimevaltval;
8383
time_tnow;
84+
structtmtmbuf;
8485

8586
gettimeofday(&tval,NULL);
8687

@@ -93,7 +94,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len)
9394
now=tval.tv_sec;
9495
strftime(timestr,ts_len,
9596
"%Y-%m-%d %H:%M:%S",
96-
localtime(&now));
97+
localtime_r(&now,&tmbuf));
9798
/* append microseconds */
9899
snprintf(timestr+strlen(timestr),ts_len-strlen(timestr),
99100
".%06u", (unsignedint) (tval.tv_usec));

‎src/template/win32

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# src/template/win32
22

3+
# define before including <time.h> for getting localtime_r() etc. on MinGW
4+
CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE"
5+
36
# Extra CFLAGS for code that will go into a shared library
47
CFLAGS_SL=""
58

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp