Mercurial > vim
diff src/memline.c @ 17135:d03a52e02f1a v8.1.1567
patch 8.1.1567: localtime_r() does not respond to $TZ changes
commit https://github.com/vim/vim/commit/db51730df1817fc4b6ecf5a065c69fac518ad821
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jun 18 22:53:24 2019 +0200
patch 8.1.1567: localtime_r() does not respond to $TZ changes
Problem: Localtime_r() does not respond to $TZ changes.
Solution: If $TZ changes then call tzset(). (Tom Ryder)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 18 Jun 2019 23:00:07 +0200 |
parents | d5e1e09a829f |
children | 31f31e938961 |
line wrap: on
line diff
--- a/src/memline.c +++ b/src/memline.c @@ -2082,6 +2082,48 @@ get_b0_dict(char_u *fname, dict_T *d) #endif /* + * Cache of the current timezone name as retrieved from TZ, or an empty string + * where unset, up to 64 octets long including trailing null byte. + */ +#if defined(HAVE_LOCALTIME_R) && defined(HAVE_TZSET) +static char tz_cache[64]; +#endif + +/* + * Call either localtime(3) or localtime_r(3) from POSIX libc time.h, with the + * latter version preferred for reentrancy. + * + * If we use localtime_r(3) and we have tzset(3) available, check to see if the + * environment variable TZ has changed since the last run, and call tzset(3) to + * update the global timezone variables if it has. This is because the POSIX + * standard doesn't require localtime_r(3) implementations to do that as it + * does with localtime(3), and we don't want to call tzset(3) every time. + */ + struct tm * +vim_localtime( + const time_t *timep, // timestamp for local representation + struct tm *result) // pointer to caller return buffer +{ +#ifdef HAVE_LOCALTIME_R +# ifdef HAVE_TZSET + char *tz; // pointer for TZ environment var + + tz = (char *)mch_getenv((char_u *)"TZ"); + if (tz == NULL) + tz = ""; + if (STRNCMP(tz_cache, tz, sizeof(tz_cache) - 1) != 0) + { + tzset(); + vim_strncpy((char_u *)tz_cache, (char_u *)tz, sizeof(tz_cache) - 1); + } +# endif // HAVE_TZSET + return localtime_r(timep, result); +#else + return localtime(timep); +#endif // HAVE_LOCALTIME_R +} + +/* * Replacement for ctime(), which is not safe to use. * Requires strftime(), otherwise returns "(unknown)". * If "thetime" is invalid returns "(invalid)". Never returns NULL. @@ -2093,16 +2135,10 @@ get_ctime(time_t thetime, int add_newlin { static char buf[50]; #ifdef HAVE_STRFTIME -# ifdef HAVE_LOCALTIME_R struct tm tmval; -# endif struct tm *curtime; -# ifdef HAVE_LOCALTIME_R - curtime = localtime_r(&thetime, &tmval); -# else - curtime = localtime(&thetime); -# endif + curtime = vim_localtime(&thetime, &tmval); /* MSVC returns NULL for an invalid value of seconds. */ if (curtime == NULL) vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1);