mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-02 07:53:43 +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
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
@ -159,6 +160,24 @@ static mode_t get_umask() {
|
||||||
return res;
|
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.
|
/// Check if the specified variable is a locale variable.
|
||||||
static bool var_is_locale(const wcstring &key) {
|
static bool var_is_locale(const wcstring &key) {
|
||||||
for (size_t i = 0; locale_variable[i]; i++) {
|
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());
|
handle_locale(key.c_str());
|
||||||
} else if (var_is_curses(key)) {
|
} else if (var_is_curses(key)) {
|
||||||
handle_curses(key.c_str());
|
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") {
|
} else if (key == L"fish_term256" || key == L"fish_term24bit") {
|
||||||
update_fish_color_support();
|
update_fish_color_support();
|
||||||
reader_react_to_color_change();
|
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.
|
/// Main test.
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
// Look for the file tests/test.fish. We expect to run in a directory containing that file.
|
// 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_races")) history_tests_t::test_history_races();
|
||||||
if (should_test_function("history_formats")) history_tests_t::test_history_formats();
|
if (should_test_function("history_formats")) history_tests_t::test_history_formats();
|
||||||
if (should_test_function("string")) test_string();
|
if (should_test_function("string")) test_string();
|
||||||
|
if (should_test_function("env_vars")) test_env_vars();
|
||||||
// history_tests_t::test_history_speed();
|
// history_tests_t::test_history_speed();
|
||||||
|
|
||||||
say(L"Encountered %d errors in low-level tests", err_count);
|
say(L"Encountered %d errors in low-level tests", err_count);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user