diff options
-rw-r--r-- | erts/emulator/beam/erl_time_sup.c | 51 | ||||
-rw-r--r-- | erts/emulator/sys/unix/erl_unix_sys.h | 21 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 1 | ||||
-rw-r--r-- | erts/emulator/sys/win32/erl_win_sys.h | 2 |
4 files changed, 33 insertions, 42 deletions
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c index d26ea19494..f262f0e5be 100644 --- a/erts/emulator/beam/erl_time_sup.c +++ b/erts/emulator/beam/erl_time_sup.c @@ -1396,17 +1396,10 @@ void get_time(int *hour, int *minute, int *second) { time_t the_clock; - struct tm *tm; -#ifdef HAVE_LOCALTIME_R - struct tm tmbuf; -#endif - + struct tm *tm, tmbuf; + the_clock = time((time_t *)0); -#ifdef HAVE_LOCALTIME_R - tm = localtime_r(&the_clock, &tmbuf); -#else - tm = localtime(&the_clock); -#endif + tm = sys_localtime_r(&the_clock, &tmbuf); *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec; @@ -1417,18 +1410,11 @@ void get_date(int *year, int *month, int *day) { time_t the_clock; - struct tm *tm; -#ifdef HAVE_LOCALTIME_R - struct tm tmbuf; -#endif + struct tm *tm, tmbuf; the_clock = time((time_t *)0); -#ifdef HAVE_LOCALTIME_R - tm = localtime_r(&the_clock, &tmbuf); -#else - tm = localtime(&the_clock); -#endif + tm = sys_localtime_r(&the_clock, &tmbuf); *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; @@ -1440,17 +1426,10 @@ get_localtime(int *year, int *month, int *day, int *hour, int *minute, int *second) { time_t the_clock; - struct tm *tm; -#ifdef HAVE_LOCALTIME_R - struct tm tmbuf; -#endif + struct tm *tm, tmbuf; the_clock = time((time_t *)0); -#ifdef HAVE_LOCALTIME_R - localtime_r(&the_clock, (tm = &tmbuf)); -#else - tm = localtime(&the_clock); -#endif + tm = sys_localtime_r(&the_clock, &tmbuf); *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; @@ -1711,11 +1690,8 @@ univ_to_local(Sint *year, Sint *month, Sint *day, Sint *hour, Sint *minute, Sint *second) { time_t the_clock; - struct tm *tm; -#ifdef HAVE_LOCALTIME_R - struct tm tmbuf; -#endif - + struct tm *tm, tmbuf; + if (!(IN_RANGE(BASEYEAR, *year, INT_MAX - 1) && IN_RANGE(1, *month, 12) && IN_RANGE(1, *day, (mdays[*month] + @@ -1727,7 +1703,7 @@ univ_to_local(Sint *year, Sint *month, Sint *day, IN_RANGE(0, *second, 59))) { return 0; } - + the_clock = *second + 60 * (*minute + 60 * (*hour + 24 * gregday(*year, *month, *day))); #ifdef HAVE_POSIX2TIME @@ -1745,11 +1721,8 @@ univ_to_local(Sint *year, Sint *month, Sint *day, the_clock = posix2time(the_clock); #endif -#ifdef HAVE_LOCALTIME_R - tm = localtime_r(&the_clock, &tmbuf); -#else - tm = localtime(&the_clock); -#endif + tm = sys_localtime_r(&the_clock, &tmbuf); + if (tm) { *year = tm->tm_year + 1900; *month = tm->tm_mon +1; diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h index ae7a3ea23e..768f412c20 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); diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 6935c0cca9..88e4cff800 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -335,7 +335,6 @@ erl_sys_init(void) if (isatty(0)) { tcgetattr(0,&initial_tty_mode); } - tzset(); /* Required at least for NetBSD with localtime_r() */ } /* signal handling */ diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h index b00ba287e2..8b6947c4e0 100644 --- a/erts/emulator/sys/win32/erl_win_sys.h +++ b/erts/emulator/sys/win32/erl_win_sys.h @@ -140,8 +140,6 @@ struct tm *sys_localtime_r(time_t *epochs, struct tm *ptm); struct tm *sys_gmtime_r(time_t *epochs, struct tm *ptm); time_t sys_mktime( struct tm *ptm); -#define localtime_r sys_localtime_r -#define HAVE_LOCALTIME_R 1 #define gmtime_r sys_gmtime_r #define HAVE_GMTIME_R #define mktime sys_mktime |