comparison 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
comparison
equal deleted inserted replaced
17134:afef6986c785 17135:d03a52e02f1a
2080 dict_add_string(d, "error", (char_u *)"Cannot open file"); 2080 dict_add_string(d, "error", (char_u *)"Cannot open file");
2081 } 2081 }
2082 #endif 2082 #endif
2083 2083
2084 /* 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
2126 /*
2085 * Replacement for ctime(), which is not safe to use. 2127 * Replacement for ctime(), which is not safe to use.
2086 * Requires strftime(), otherwise returns "(unknown)". 2128 * Requires strftime(), otherwise returns "(unknown)".
2087 * If "thetime" is invalid returns "(invalid)". Never returns NULL. 2129 * If "thetime" is invalid returns "(invalid)". Never returns NULL.
2088 * When "add_newline" is TRUE add a newline like ctime() does. 2130 * When "add_newline" is TRUE add a newline like ctime() does.
2089 * Uses a static buffer. 2131 * Uses a static buffer.
2091 char * 2133 char *
2092 get_ctime(time_t thetime, int add_newline) 2134 get_ctime(time_t thetime, int add_newline)
2093 { 2135 {
2094 static char buf[50]; 2136 static char buf[50];
2095 #ifdef HAVE_STRFTIME 2137 #ifdef HAVE_STRFTIME
2096 # ifdef HAVE_LOCALTIME_R
2097 struct tm tmval; 2138 struct tm tmval;
2098 # endif
2099 struct tm *curtime; 2139 struct tm *curtime;
2100 2140
2101 # ifdef HAVE_LOCALTIME_R 2141 curtime = vim_localtime(&thetime, &tmval);
2102 curtime = localtime_r(&thetime, &tmval);
2103 # else
2104 curtime = localtime(&thetime);
2105 # endif
2106 /* MSVC returns NULL for an invalid value of seconds. */ 2142 /* MSVC returns NULL for an invalid value of seconds. */
2107 if (curtime == NULL) 2143 if (curtime == NULL)
2108 vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1); 2144 vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1);
2109 else 2145 else
2110 (void)strftime(buf, sizeof(buf) - 1, "%a %b %d %H:%M:%S %Y", curtime); 2146 (void)strftime(buf, sizeof(buf) - 1, "%a %b %d %H:%M:%S %Y", curtime);