@@ -2081,6 +2081,48 @@ get_b0_dict(char_u *fname, dict_T *d)
20812081}
20822082#endif
20832083
2084+ /*
2085+ * Cache of the current timezone name as retrieved from TZ, or an empty string
2086+ * where unset, up to 64 octets long including trailing null byte.
2087+ */
2088+ #if defined(HAVE_LOCALTIME_R ) && defined(HAVE_TZSET )
2089+ static char tz_cache [64 ];
2090+ #endif
2091+
2092+ /*
2093+ * Call either localtime(3) or localtime_r(3) from POSIX libc time.h, with the
2094+ * latter version preferred for reentrancy.
2095+ *
2096+ * If we use localtime_r(3) and we have tzset(3) available, check to see if the
2097+ * environment variable TZ has changed since the last run, and call tzset(3) to
2098+ * update the global timezone variables if it has. This is because the POSIX
2099+ * standard doesn't require localtime_r(3) implementations to do that as it
2100+ * does with localtime(3), and we don't want to call tzset(3) every time.
2101+ */
2102+ struct tm *
2103+ vim_localtime (
2104+ const time_t * timep , // timestamp for local representation
2105+ struct tm * result ) // pointer to caller return buffer
2106+ {
2107+ #ifdef HAVE_LOCALTIME_R
2108+ # ifdef HAVE_TZSET
2109+ char * tz ; // pointer for TZ environment var
2110+
2111+ tz = (char * )mch_getenv ((char_u * )"TZ" );
2112+ if (tz == NULL )
2113+ tz = "" ;
2114+ if (STRNCMP (tz_cache , tz , sizeof (tz_cache ) - 1 ) != 0 )
2115+ {
2116+ tzset ();
2117+ vim_strncpy ((char_u * )tz_cache , (char_u * )tz , sizeof (tz_cache ) - 1 );
2118+ }
2119+ # endif // HAVE_TZSET
2120+ return localtime_r (timep , result );
2121+ #else
2122+ return localtime (timep );
2123+ #endif // HAVE_LOCALTIME_R
2124+ }
2125+
20842126/*
20852127 * Replacement for ctime(), which is not safe to use.
20862128 * Requires strftime(), otherwise returns "(unknown)".
@@ -2093,16 +2135,10 @@ get_ctime(time_t thetime, int add_newline)
20932135{
20942136 static char buf [50 ];
20952137#ifdef HAVE_STRFTIME
2096- # ifdef HAVE_LOCALTIME_R
20972138 struct tm tmval ;
2098- # endif
20992139 struct tm * curtime ;
21002140
2101- # ifdef HAVE_LOCALTIME_R
2102- curtime = localtime_r (& thetime , & tmval );
2103- # else
2104- curtime = localtime (& thetime );
2105- # endif
2141+ curtime = vim_localtime (& thetime , & tmval );
21062142 /* MSVC returns NULL for an invalid value of seconds. */
21072143 if (curtime == NULL )
21082144 vim_strncpy ((char_u * )buf , (char_u * )_ ("(Invalid)" ), sizeof (buf ) - 1 );
0 commit comments