diff --git a/headers/private/kernel/real_time_clock.h b/headers/private/kernel/real_time_clock.h index 1afcae465d..a9ba0043cc 100644 --- a/headers/private/kernel/real_time_clock.h +++ b/headers/private/kernel/real_time_clock.h @@ -35,8 +35,10 @@ uint32 get_timezone_offset(void); bigtime_t _user_system_time(void); status_t _user_set_real_time_clock(uint32 time); -status_t _user_set_timezone(int32 timezoneOffset); -status_t _user_get_timezone(int32 *_timezoneOffset); +status_t _user_set_timezone(int32 timezoneOffset, const char *name, + size_t nameLength); +status_t _user_get_timezone(int32 *_timezoneOffset, char* name, + size_t nameLength); status_t _user_set_real_time_clock_is_gmt(bool isGMT); status_t _user_get_real_time_clock_is_gmt(bool *_isGMT); diff --git a/headers/private/libroot/locale/ICUTimeConversion.h b/headers/private/libroot/locale/ICUTimeConversion.h index a5065c5b8b..a614a203df 100644 --- a/headers/private/libroot/locale/ICUTimeConversion.h +++ b/headers/private/libroot/locale/ICUTimeConversion.h @@ -8,6 +8,8 @@ #include +#include + #include "ICUTimeData.h" #include "LocaleBackend.h" @@ -39,7 +41,7 @@ private: TimeConversionDataBridge* fDataBridge; - char fTimeZoneID[64]; + char fTimeZoneID[B_FILE_NAME_LENGTH]; }; diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 9cfbb60090..6cda990134 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -363,8 +363,10 @@ extern status_t _kern_stop_watching(dev_t device, ino_t node, port_id port, // time functions extern status_t _kern_set_real_time_clock(uint32 time); -extern status_t _kern_set_timezone(int32 timezoneOffset); -extern status_t _kern_get_timezone(int32 *_timezoneOffset); +extern status_t _kern_set_timezone(int32 timezoneOffset, const char *name, + size_t nameLength); +extern status_t _kern_get_timezone(int32 *_timezoneOffset, char *name, + size_t nameLength); extern status_t _kern_set_real_time_clock_is_gmt(bool isGMT); extern status_t _kern_get_real_time_clock_is_gmt(bool *_isGMT); diff --git a/src/bin/clockconfig.cpp b/src/bin/clockconfig.cpp index 9bd7743c5e..07c0df1ede 100644 --- a/src/bin/clockconfig.cpp +++ b/src/bin/clockconfig.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -62,14 +63,21 @@ setTimeZoneOffset(BPath path) fprintf(stderr, "%s: unable to parse Time settings file\n", program); return; } + BString timeZoneName; + if (settings.FindString("timezone", &timeZoneName) != B_OK) { + fprintf(stderr, "%s: no timezone found\n", program); + return; + } int32 timeZoneOffset; if (settings.FindInt32("offset", &timeZoneOffset) != B_OK) { fprintf(stderr, "%s: no timezone offset found\n", program); return; } - _kern_set_timezone(timeZoneOffset); - printf("timezone offset is %ld seconds from GMT.\n", timeZoneOffset); + _kern_set_timezone(timeZoneOffset, timeZoneName.String(), + timeZoneName.Length()); + printf("timezone is %s, offset is %ld seconds from GMT.\n", + timeZoneName.String(), timeZoneOffset); } diff --git a/src/preferences/time/ZoneView.cpp b/src/preferences/time/ZoneView.cpp index f5eaef9829..fbeb39fcc2 100644 --- a/src/preferences/time/ZoneView.cpp +++ b/src/preferences/time/ZoneView.cpp @@ -360,21 +360,8 @@ TimeZoneView::_SetSystemTimeZone() gMutableLocaleRoster->SetDefaultTimeZone(timeZone); - _kern_set_timezone(timeZone.OffsetFromGMT()); - - BPath path; - status_t status = find_directory(B_COMMON_SETTINGS_DIRECTORY, &path, true); - BFile file; - if (status == B_OK) { - path.Append("libroot_timezone_info"); - status = file.SetTo(path.Path(), - B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); - } - if (status == B_OK) { - const BString& timeZoneID = timeZone.Code(); - file.Write(timeZoneID.String(), timeZoneID.Length()); - file.Sync(); - } + _kern_set_timezone(timeZone.OffsetFromGMT(), timeZone.Code().String(), + timeZone.Code().Length()); fSetZone->SetEnabled(false); fLastUpdateMinute = -1; diff --git a/src/system/kernel/real_time_clock.cpp b/src/system/kernel/real_time_clock.cpp index 3a170d49df..2ef8569453 100644 --- a/src/system/kernel/real_time_clock.cpp +++ b/src/system/kernel/real_time_clock.cpp @@ -32,6 +32,7 @@ static struct real_time_data *sRealTimeData; static bool sIsGMT = false; static bigtime_t sTimezoneOffset = 0; +static char sTimezoneName[B_FILE_NAME_LENGTH] = "GMT"; /*! Write the system time to CMOS. */ @@ -217,7 +218,7 @@ _user_set_real_time_clock(uint32 time) status_t -_user_set_timezone(time_t timezoneOffset) +_user_set_timezone(time_t timezoneOffset, const char *name, size_t nameLength) { bigtime_t offset = (bigtime_t)timezoneOffset * 1000000LL; @@ -228,6 +229,12 @@ _user_set_timezone(time_t timezoneOffset) arch_rtc_get_system_time_offset(sRealTimeData), sTimezoneOffset, offset, sIsGMT)); + if (name != NULL && nameLength > 0) { + if (!IS_USER_ADDRESS(name) + || user_strlcpy(sTimezoneName, name, sizeof(sTimezoneName)) < 0) + return B_BAD_ADDRESS; + } + // We only need to update our time offset if the hardware clock // does not run in the local timezone. // Since this is shared data, we need to update it atomically. @@ -247,12 +254,18 @@ _user_set_timezone(time_t timezoneOffset) status_t -_user_get_timezone(time_t *_timezoneOffset) +_user_get_timezone(time_t *_timezoneOffset, char *userName, size_t nameLength) { time_t offset = (time_t)(sTimezoneOffset / 1000000LL); - if (!IS_USER_ADDRESS(_timezoneOffset) - || user_memcpy(_timezoneOffset, &offset, sizeof(time_t)) < B_OK) + if (_timezoneOffset != NULL + && (!IS_USER_ADDRESS(_timezoneOffset) + || user_memcpy(_timezoneOffset, &offset, sizeof(time_t)) < B_OK)) + return B_BAD_ADDRESS; + + if (userName != NULL + && (!IS_USER_ADDRESS(userName) + || user_strlcpy(userName, sTimezoneName, nameLength) < 0)) return B_BAD_ADDRESS; return B_OK; diff --git a/src/system/libroot/posix/time/localtime.cpp b/src/system/libroot/posix/time/localtime.cpp index 26db09f6c5..527a3a52f1 100644 --- a/src/system/libroot/posix/time/localtime.cpp +++ b/src/system/libroot/posix/time/localtime.cpp @@ -5,12 +5,12 @@ #include -#include #include #include #include -#include +#include + #include #include "LocaleBackend.h" @@ -38,31 +38,16 @@ tzset(void) if (gLocaleBackend == NULL && LocaleBackend::LoadBackend() != B_OK) return; - char timeZoneID[64] = { "GMT" }; + char timeZoneID[B_FILE_NAME_LENGTH] = { "GMT" }; const char* tz = getenv("TZ"); if (tz != NULL) strlcpy(timeZoneID, tz, sizeof(timeZoneID)); - else { - do { - char path[B_PATH_NAME_LENGTH]; - if (find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false, path, - sizeof(path)) < 0) - break; - strlcat(path, "/libroot_timezone_info", sizeof(path)); + else + _kern_get_timezone(NULL, timeZoneID, sizeof(timeZoneID)); - FILE* tzInfoFile = fopen(path, "r"); - if (tzInfoFile == NULL) - break; - - fgets(timeZoneID, sizeof(timeZoneID), tzInfoFile); - fclose(tzInfoFile); - } while(0); - } - - if (gLocaleBackend != NULL) { + if (gLocaleBackend != NULL) gLocaleBackend->TZSet(timeZoneID); - } }