Be more careful when documenting tm_zone, tm_gmtoff, tzname, etc.,
in the light of POSIX.1-2024 etc.
---
Makefile | 8 ++++--
newctime.3 | 79 ++++++++++++++++++++++++---------------------------
newstrftime.3 | 14 ++++-----
newtzset.3 | 55 +++++++++++++++++++++++++++++++----
4 files changed, 100 insertions(+), 56 deletions(-)
diff --git a/Makefile b/Makefile
index 99f2f56b..d6d66a1f 100644
--- a/Makefile
+++ b/Makefile
@@ -358,7 +358,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
# # -DHAVE_TZNAME=0 # do not support "tzname"
# # -DHAVE_TZNAME=1 # support "tzname", which is defined by system library
# # -DHAVE_TZNAME=2 # support and define "tzname"
-# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later.
+# # to the "CFLAGS=" line. Although "tzname" is required by POSIX.1-1988
+# # and later, its contents are unspecified if you use a geographical TZ
+# # and the variable is planned to be removed in a future POSIX edition.
# # If not defined, the code attempts to guess HAVE_TZNAME from other macros.
# # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause
# # crashes when combined with some platforms' standard libraries,
@@ -369,7 +371,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
# # -DUSG_COMPAT=1 # support, and variables are defined by system library
# # -DUSG_COMPAT=2 # support and define variables
# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by Unix
-# # Systems Group code and are required by POSIX.1-2008 and later (with XSI).
+# # Systems Group code and are required by POSIX.1-2008 and later (with XSI),
+# # although their contents are unspecified if you use a geographical TZ
+# # and the variables are planned to be rmeoved in a future edition of POSIX.
# # If not defined, the code attempts to guess USG_COMPAT from other macros.
# #
# # To support the external variable "altzone", add
diff --git a/newctime.3 b/newctime.3
index ccc19748..d19fd25b 100644
--- a/newctime.3
+++ b/newctime.3
@@ -9,8 +9,6 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
.el .ds - \-
.B #include <time.h>
.PP
-.BR "extern char *tzname[];" " /\(** (optional) \(**/"
-.PP
.B [[deprecated]] char *ctime(time_t const *clock);
.PP
/* Only in POSIX.1-2017 and earlier. */
@@ -114,17 +112,6 @@ The
function
corrects for the time zone and any time zone adjustments
(such as Daylight Saving Time in the United States).
-After filling in the
-.q "tm"
-structure,
-.B localtime
-sets the
-.BR tm_isdst 'th
-element of
-.B tzname
-to a pointer to a string that's the time zone abbreviation to be used with
-.BR localtime 's
-return value.
.PP
The
.B gmtime
@@ -294,21 +281,43 @@ from UT, with positive values indicating east
of the Prime Meridian.
The field's name is derived from Greenwich Mean Time, a precursor of UT.
.PP
-In
+In platforms conforming to POSIX.1-2024 the
.B "struct tm"
the
.B tm_zone
and
.B tm_gmtoff
-fields exist, and are filled in, only if arrangements to do
-so were made when the library containing these functions was
-created.
-Similarly, the
-.B tzname
-variable is optional; also, there is no guarantee that
-.B tzname
-will
-continue to exist in this form in future releases of this code.
+fields exist, and are filled in.
+For
+.B localtime_rz
+and
+.B mktime_rz
+the storage lifetime of the strings addressed by
+.B tm_zone
+extends until the corresponding
+.B timezone_t
+object is freed via
+.BR tzfree .
+For the other functions the lifetime extends until the
+.I TZ
+environment variable changes state and
+.B tzset
+is then called.
+.PP
+As a side effect, the
+.BR ctime ,
+.B localtime
+and
+.B mktime
+functions also behave as if
+.B tzset
+were called.
+The
+.B ctime_r
+and
+.B localtime_r
+functions might (or might not) also behave this way.
+This is for compatibility with older platforms, as required by POSIX.
.SH FILES
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
/etc/localtime local timezone file
@@ -322,11 +331,11 @@ continue to exist in this form in future releases of this code.
If /usr/share/zoneinfo/GMT is absent,
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
.SH SEE ALSO
-getenv(3),
-newstrftime(3),
-newtzset(3),
-time(2),
-tzfile(5)
+.BR getenv (3),
+.BR newstrftime (3),
+.BR newtzset (3),
+.BR time (2),
+.BR tzfile (5).
.SH NOTES
The return values of
.BR asctime ,
@@ -336,20 +345,6 @@ and
.B localtime
point to static data
overwritten by each call.
-The
-.B tzname
-variable (once set) and the
-.B tm_zone
-field of a returned
-.B "struct tm"
-both point to an array of characters that
-can be freed or overwritten by later calls to the functions
-.BR localtime ,
-.BR tzfree ,
-and
-.BR tzset ,
-if these functions affect the timezone information that specifies the
-abbreviation in question.
The remaining functions and data are thread-safe.
.PP
The
diff --git a/newstrftime.3 b/newstrftime.3
index 11e37ae8..a9997a09 100644
--- a/newstrftime.3
+++ b/newstrftime.3
@@ -398,7 +398,7 @@ also behaves as if
were called.
This is for compatibility with older platforms, as required by POSIX;
it is not needed for
-.BR tzset 's
+.BR strftime 's
own use.
.SH "RETURN VALUE"
If the conversion is successful,
@@ -428,11 +428,11 @@ conversion and the number of seconds since the Epoch cannot be represented
in a
.c time_t .
.SH SEE ALSO
-date(1),
-getenv(3),
-newctime(3),
-newtzset(3),
-time(2),
-tzfile(5)
+.BR date (1),
+.BR getenv (3),
+.BR newctime (3),
+.BR newtzset (3),
+.BR time (2),
+.BR tzfile (5).
.SH BUGS
There is no conversion specification for the phase of the moon.
diff --git a/newtzset.3 b/newtzset.3
index 4708106d..661fb25b 100644
--- a/newtzset.3
+++ b/newtzset.3
@@ -15,6 +15,14 @@ tzset \- initialize time conversion information
.PP
.B void tzset(void);
.PP
+/\(** Optional and obsolescent: \(**/
+.br
+.B extern char *tzname[];
+.br
+.B extern long timezone;
+.br
+.B extern int daylight;
+.PP
.B cc ... \*-ltz
.fi
.SH DESCRIPTION
@@ -341,6 +349,22 @@ if the implied call to
fails,
.B tzset
falls back on UT.
+.PP
+As a side effect, the
+.B tzset
+function sets some external variables if the platform defines them.
+It sets
+.BR tzname [0]
+and
+.BR tzname [1]
+to pointers to strings that are time zone abbreviations to be used with
+standard and daylight saving time, respectively.
+It also sets
+.B timezone
+to be the number of seconds that standard time is west of the Prime Meridian,
+and
+.B daylight
+to be zero if daylight saving time is never in effect, non-zero otherwise.
.SH "RETURN VALUE"
If successful, the
.B tzalloc
@@ -379,8 +403,29 @@ and
If /usr/share/zoneinfo/GMT is absent,
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
.SH SEE ALSO
-getenv(3),
-newctime(3),
-newstrftime(3),
-time(2),
-tzfile(5)
+.BR getenv (3),
+.BR newctime (3),
+.BR newstrftime (3),
+.BR time (2),
+.BR tzfile (5).
+.SH NOTES
+Portable code should not rely on the contents of the external variables
+.BR tzname ,
+.B timezone
+and
+.B daylight
+as their contents are unspecified (and do not make sense in general)
+when a geographical TZ is used.
+In multithreaded applications behavior is undefined if one thread accesses
+one of these variables while another thread invokes
+.BR tzset .
+A future version of POSIX is planned to remove these variables;
+callers can instead use the
+.I tm_gmtoff
+and
+.I tm_zone
+members of
+.B struct tm,
+or use
+.B strftime
+with "%z" or "%Z".
--
2.43.0