mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
reset timezone state when TZ env var changes
When the TZ env var is modified change fish's internal timezone state. Fixes #3181.
This commit is contained in:
parent
44cde9e0e9
commit
dda890cf88
21
src/env.cpp
21
src/env.cpp
|
@ -13,6 +13,7 @@
|
|||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
@ -159,6 +160,24 @@ static mode_t get_umask() {
|
|||
return res;
|
||||
}
|
||||
|
||||
/// Check if the specified variable is a locale variable.
|
||||
static bool var_is_timezone(const wcstring &key) { return key == L"TZ"; }
|
||||
|
||||
/// Properly sets all locale information.
|
||||
static void handle_timezone(const wchar_t *env_var_name) {
|
||||
debug(2, L"handle_timezone() called in response to '%ls' changing", env_var_name);
|
||||
const env_var_t val = env_get_string(env_var_name, ENV_EXPORT);
|
||||
const std::string &value = wcs2string(val);
|
||||
const std::string &name = wcs2string(env_var_name);
|
||||
debug(2, L"timezone var %s='%s'", name.c_str(), value.c_str());
|
||||
if (val.empty()) {
|
||||
unsetenv(name.c_str());
|
||||
} else {
|
||||
setenv(name.c_str(), value.c_str(), 1);
|
||||
}
|
||||
tzset();
|
||||
}
|
||||
|
||||
/// Check if the specified variable is a locale variable.
|
||||
static bool var_is_locale(const wcstring &key) {
|
||||
for (size_t i = 0; locale_variable[i]; i++) {
|
||||
|
@ -234,6 +253,8 @@ static void react_to_variable_change(const wcstring &key) {
|
|||
handle_locale(key.c_str());
|
||||
} else if (var_is_curses(key)) {
|
||||
handle_curses(key.c_str());
|
||||
} else if (var_is_timezone(key)) {
|
||||
handle_timezone(key.c_str());
|
||||
} else if (key == L"fish_term256" || key == L"fish_term24bit") {
|
||||
update_fish_color_support();
|
||||
reader_react_to_color_change();
|
||||
|
|
|
@ -3780,6 +3780,42 @@ static void test_string(void) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper for test_timezone_env_vars().
|
||||
long return_timezone_hour(time_t tstamp, const wchar_t *timezone) {
|
||||
struct tm ltime;
|
||||
char ltime_str[3];
|
||||
char *str_ptr;
|
||||
int n;
|
||||
|
||||
env_set(L"TZ", timezone, ENV_EXPORT);
|
||||
localtime_r(&tstamp, <ime);
|
||||
n = strftime(ltime_str, 3, "%H", <ime);
|
||||
if (n != 2) {
|
||||
err(L"strftime() returned %d, expected 2", n);
|
||||
return 0;
|
||||
}
|
||||
return strtol(ltime_str, &str_ptr, 10);
|
||||
}
|
||||
|
||||
/// Verify that setting special env vars have the expected effect on the current shell process.
|
||||
static void test_timezone_env_vars(void) {
|
||||
// Confirm changing the timezone affects fish's idea of the local time.
|
||||
time_t tstamp = time(NULL);
|
||||
|
||||
long first_tstamp = return_timezone_hour(tstamp, L"UTC-1");
|
||||
long second_tstamp = return_timezone_hour(tstamp, L"UTC-2");
|
||||
long delta = second_tstamp - first_tstamp;
|
||||
if (delta != 1 && delta != -23) {
|
||||
err(L"expected a one hour timezone delta got %ld", delta);
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify that setting special env vars have the expected effect on the current shell process.
|
||||
static void test_env_vars(void) {
|
||||
test_timezone_env_vars();
|
||||
// TODO: Add tests for the locale and ncurses vars.
|
||||
}
|
||||
|
||||
/// Main test.
|
||||
int main(int argc, char **argv) {
|
||||
// Look for the file tests/test.fish. We expect to run in a directory containing that file.
|
||||
|
@ -3869,6 +3905,7 @@ int main(int argc, char **argv) {
|
|||
if (should_test_function("history_races")) history_tests_t::test_history_races();
|
||||
if (should_test_function("history_formats")) history_tests_t::test_history_formats();
|
||||
if (should_test_function("string")) test_string();
|
||||
if (should_test_function("env_vars")) test_env_vars();
|
||||
// history_tests_t::test_history_speed();
|
||||
|
||||
say(L"Encountered %d errors in low-level tests", err_count);
|
||||
|
|
Loading…
Reference in New Issue
Block a user