View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001794 | 1003.1(2016/18)/Issue7+TC2 | System Interfaces | public | 2024-01-06 23:11 | 2024-01-06 23:11 |
Reporter | steffen | Assigned To | |||
Priority | normal | Severity | Editorial | Type | Enhancement Request |
Status | New | Resolution | Open | ||
Name | steffen | ||||
Organization | |||||
User Reference | |||||
Section | localtime, gmtime | ||||
Page Number | in transit | ||||
Line Number | (Line or range of lines) | ||||
Interp Status | |||||
Final Accepted Text | |||||
Summary | 0001794: Please add tzalloc/tzfree and localtime_rz, mktime_z interfaces | ||||
Description | [I copy a mail from austin-group-l@] As stated in [1] the localtime() and mktime() series of functions have the inherent problem of not being thread-safe regarding possible changes to the time zone: in a pure POSIX environment changes to TZ always affect global data. If my memory serves correctly, about a decade ago the NetBSD project contacted the IANA TZ maintainer in order to upstream a new, truly thread-safe interface that addresses this issue. Since some time in 2014 (see [1]) the IANA TZ database, which includes the Public Domain aka open source code as is used by many projects to implement the time related programming interface, includes a new series of functions: timezone_t tzalloc(char const *TZ); void tzfree(timezone_t tz); struct tm *localtime_rz(timezone_t restrict zone, time_t const *restrict clock, struct tm *restrict result); struct tm *restrict tm); time_t mktime_z(timezone_t restrict zone, struct tm *restrict tm); [1] https://austingroupbugs.net/view.php?id=1788 If POSIX would offer this interface, the open source (public domain) code and manual of which are available via the IANA TZ, truly "thread-safe" time programming becomes possible in POSIX. This is especially important if no CLOCK_TAI is available. For an example, here is what the widely used NTP server chrony performs in order to achieve its task: tm = gmtime(&when); if (!tm) return tz_leap; stm = *tm; /* Temporarily switch to the timezone containing leap seconds */ tz_env = getenv("TZ"); if (tz_env) { if (strlen(tz_env) >= sizeof (tz_orig)) return tz_leap; strcpy(tz_orig, tz_env); } setenv("TZ", leap_tzname, 1); tzset(); /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */ t = mktime(&stm); if (t != -1) tz_tai_offset = t - when + 10; /* Set the time to 23:59:60 and see how it overflows in mktime() */ stm.tm_sec = 60; stm.tm_min = 59; stm.tm_hour = 23; t = mktime(&stm); if (tz_env) setenv("TZ", tz_orig, 1); else unsetenv("TZ"); tzset(); if (t == -1) return tz_leap; if (stm.tm_sec == 60) tz_leap = LEAP_InsertSecond; else if (stm.tm_sec == 1) tz_leap = LEAP_DeleteSecond; *tai_offset = tz_tai_offset; This is especially important if no CLOCK_TAI is available. For an example, here is what the widely used NTP server chrony performs in order to achieve its task: tm = gmtime(&when); if (!tm) return tz_leap; stm = *tm; /* Temporarily switch to the timezone containing leap seconds */ tz_env = getenv("TZ"); if (tz_env) { if (strlen(tz_env) >= sizeof (tz_orig)) return tz_leap; strcpy(tz_orig, tz_env); } setenv("TZ", leap_tzname, 1); tzset(); /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */ t = mktime(&stm); if (t != -1) tz_tai_offset = t - when + 10; /* Set the time to 23:59:60 and see how it overflows in mktime() */ stm.tm_sec = 60; stm.tm_min = 59; stm.tm_hour = 23; t = mktime(&stm); if (tz_env) setenv("TZ", tz_orig, 1); else unsetenv("TZ"); tzset(); if (t == -1) return tz_leap; if (stm.tm_sec == 60) tz_leap = LEAP_InsertSecond; else if (stm.tm_sec == 1) tz_leap = LEAP_DeleteSecond; *tai_offset = tz_tai_offset; I want to point out that setting an environment variable can be a costly operation, but moreover changing the timezone as such may involve several file system operations, being a potentially very expensive operation. (By the way the draft 4 uses "file system" as well as "filesystem".) With the new interface two timezone objects can be preallocated, and the operations are totally detached from global data and multithread-safe. | ||||
Desired Action | Please sponsor and add the tzalloc/tzfree and localtime_rz, mktime_z interfaces. They are already available on NetBSD, and soon will be released on Android. The Public Domain code of the IANA TZ includes these functions and their manual pages; its' maintainer is also a major contributor to the most widely used Linux C library (ie a code sync is to be expected fast as necessary). | ||||
Tags | No tags attached. |