mirror of
https://github.com/neovim/neovim.git
synced 2025-10-04 17:06:30 +00:00
vim-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)
db51730df1
This commit is contained in:
@@ -2,9 +2,6 @@
|
|||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
@@ -13,7 +10,7 @@
|
|||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/main.h"
|
#include "nvim/main.h"
|
||||||
|
|
||||||
static uv_mutex_t delay_mutex;
|
static uv_mutex_t delay_mutex;
|
||||||
@@ -112,6 +109,10 @@ void os_microdelay(uint64_t us, bool ignoreinput)
|
|||||||
uv_mutex_unlock(&delay_mutex);
|
uv_mutex_unlock(&delay_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
static char tz_cache[64];
|
||||||
|
|
||||||
/// Portable version of POSIX localtime_r()
|
/// Portable version of POSIX localtime_r()
|
||||||
///
|
///
|
||||||
/// @return NULL in case of error
|
/// @return NULL in case of error
|
||||||
@@ -120,6 +121,19 @@ struct tm *os_localtime_r(const time_t *restrict clock,
|
|||||||
{
|
{
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
// POSIX provides localtime_r() as a thread-safe version of localtime().
|
// POSIX provides localtime_r() as a thread-safe version of localtime().
|
||||||
|
//
|
||||||
|
// Check to see if the environment variable TZ has changed since the last run.
|
||||||
|
// Call tzset(3) to update the global timezone variables if it has.
|
||||||
|
// POSIX standard doesn't require localtime_r() implementations to do that
|
||||||
|
// as it does with localtime(), and we don't want to call tzset() every time.
|
||||||
|
const char *tz = os_getenv("TZ");
|
||||||
|
if (tz == NULL) {
|
||||||
|
tz = "";
|
||||||
|
}
|
||||||
|
if (strncmp(tz_cache, tz, sizeof(tz_cache) - 1) != 0) {
|
||||||
|
tzset();
|
||||||
|
xstrlcpy(tz_cache, tz, sizeof(tz_cache));
|
||||||
|
}
|
||||||
return localtime_r(clock, result); // NOLINT(runtime/threadsafe_fn)
|
return localtime_r(clock, result); // NOLINT(runtime/threadsafe_fn)
|
||||||
#else
|
#else
|
||||||
// Windows version of localtime() is thread-safe.
|
// Windows version of localtime() is thread-safe.
|
||||||
|
@@ -186,6 +186,29 @@ func Test_strftime()
|
|||||||
|
|
||||||
call assert_fails('call strftime([])', 'E730:')
|
call assert_fails('call strftime([])', 'E730:')
|
||||||
call assert_fails('call strftime("%Y", [])', 'E745:')
|
call assert_fails('call strftime("%Y", [])', 'E745:')
|
||||||
|
|
||||||
|
" Check that the time changes after we change the timezone
|
||||||
|
" Save previous timezone value, if any
|
||||||
|
if exists('$TZ')
|
||||||
|
let tz = $TZ
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Force EST and then UTC, save the current hour (24-hour clock) for each
|
||||||
|
let $TZ = 'EST' | let est = strftime('%H')
|
||||||
|
let $TZ = 'UTC' | let utc = strftime('%H')
|
||||||
|
|
||||||
|
" Those hours should be two bytes long, and should not be the same; if they
|
||||||
|
" are, a tzset(3) call may have failed somewhere
|
||||||
|
call assert_equal(strlen(est), 2)
|
||||||
|
call assert_equal(strlen(utc), 2)
|
||||||
|
call assert_notequal(est, utc)
|
||||||
|
|
||||||
|
" If we cached a timezone value, put it back, otherwise clear it
|
||||||
|
if exists('tz')
|
||||||
|
let $TZ = tz
|
||||||
|
else
|
||||||
|
unlet $TZ
|
||||||
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_resolve()
|
func Test_resolve()
|
||||||
|
Reference in New Issue
Block a user