summaryrefslogtreecommitdiff
path: root/erts/emulator/sys/unix/erl_unix_sys.h
diff options
context:
space:
mode:
authorLukas Larsson <lukas@erlang.org>2022-05-02 08:32:54 +0200
committerLukas Larsson <lukas@erlang.org>2022-05-02 08:32:54 +0200
commit56e75b1a1f07feee4786db38d4f034ca03d96f61 (patch)
treef48bbaf7396df384c2b7b0dcc8142aad5f9fdff8 /erts/emulator/sys/unix/erl_unix_sys.h
parent9c4a05adc929e4f3a4263552ef17069df263aae7 (diff)
parent5ee1d5909e9b0ce02dc5334f7f03f3ec3c7565f3 (diff)
downloaderlang-56e75b1a1f07feee4786db38d4f034ca03d96f61.tar.gz
Merge branch 'lukas/22/erts/fix-localtime-tz-change/OTP-18076' into maint
* lukas/22/erts/fix-localtime-tz-change/OTP-18076: erts: Fix localtime_r summer/winter-time change bug
Diffstat (limited to 'erts/emulator/sys/unix/erl_unix_sys.h')
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 7cddd4e2b7..9287808370 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -318,6 +318,27 @@ int sys_stop_hrvtime(void);
/* No use in having other resolutions than 1 Ms. */
#define SYS_CLOCK_RESOLUTION 1
+ERTS_GLB_INLINE struct tm *sys_localtime_r(time_t *the_clock, struct tm *buff);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE struct tm *sys_localtime_r(time_t *the_clock, struct tm *buff) {
+#ifdef HAVE_LOCALTIME_R
+ tzset(); /* POSIX.1-2004 does not require tzset to be called within
+ localtime_r, so if summer/winter-time has passed localtime_r
+ will return the time when Erlang was started. So we need to
+ call tzset() before all localtime_r calls.
+
+ localtime already calls tzset for each call, so the performance
+ penalty should be acceptable.... */
+ return localtime_r(the_clock, buff);
+#else
+ return localtime(the_clock);
+#endif
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
/* These are defined in sys.c */
typedef void (*SIGFUNC)(int);
extern SIGFUNC sys_signal(int, SIGFUNC);