From: Paul Eggert Date: Tue, 6 Feb 2024 06:48:29 +0000 (-0800) Subject: ctime: improve doc X-Git-Tag: v1.0~466 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=92a981f18fb8eea357336bcd6638b37ac36aaa4d;p=gnulib.git ctime: improve doc * doc/posix-functions/asctime.texi (asctime): * doc/posix-functions/asctime_r.texi (asctime_r): * doc/posix-functions/ctime_r.texi (ctime_r): * doc/posix-functions/ctime.texi (ctime): Mention locale problem of strftime more consistently. Improve wording. For ctime and ctime_r, mention that localtime_r can fail. * doc/posix-functions/ctime.texi (ctime): Move history section to end and spiff up a bit. * doc/posix-functions/ctime_r.texi (ctime_r): Omit commentary that assumes traditional SunOS ctime_r API; it was confusing and not useful for Gnulib apps, which assume the POSIX API. --- diff --git a/ChangeLog b/ChangeLog index 2e774f6114..4813e18c7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2024-02-03 Paul Eggert + + ctime: improve doc + * doc/posix-functions/asctime.texi (asctime): + * doc/posix-functions/asctime_r.texi (asctime_r): + * doc/posix-functions/ctime_r.texi (ctime_r): + * doc/posix-functions/ctime.texi (ctime): + Mention locale problem of strftime more consistently. Improve + wording. For ctime and ctime_r, mention that localtime_r can + fail. + * doc/posix-functions/ctime.texi (ctime): Move history section + to end and spiff up a bit. + * doc/posix-functions/ctime_r.texi (ctime_r): Omit commentary that + assumes traditional SunOS ctime_r API; it was confusing and not + useful for Gnulib apps, which assume the POSIX API. + 2024-02-05 Bruno Haible Further improve cross-compilation for midipix. diff --git a/doc/posix-functions/asctime.texi b/doc/posix-functions/asctime.texi index 7b19deaa22..13aae8385a 100644 --- a/doc/posix-functions/asctime.texi +++ b/doc/posix-functions/asctime.texi @@ -17,8 +17,9 @@ This function is deprecated in C23. Likewise, POSIX says this function is obsolescent and it is planned to be removed in a future version. Portable applications can use @code{strftime} (or even @code{sprintf}) instead. +However, @code{strftime} is locale dependent. @item This function may overflow its internal buffer if its argument -specifies a time before the year 1000 or after the year 9999. +specifies a year before 1000 or after 9999. @xref{ctime}. @end itemize diff --git a/doc/posix-functions/asctime_r.texi b/doc/posix-functions/asctime_r.texi index ae527bd197..e948d3c47b 100644 --- a/doc/posix-functions/asctime_r.texi +++ b/doc/posix-functions/asctime_r.texi @@ -24,8 +24,9 @@ mingw, MSVC 14. POSIX says this function is obsolescent and it is planned to be removed in a future version. Use the function @code{strftime} (or even @code{sprintf}) instead. +However, @code{strftime} is locale dependent. @item This function may overflow its output buffer if its argument -specifies a time before the year 1000 or after the year 9999. +specifies a year before 1000 or after 9999. @xref{ctime}. @end itemize diff --git a/doc/posix-functions/ctime.texi b/doc/posix-functions/ctime.texi index 76c6e0ffe0..3a1aa489f4 100644 --- a/doc/posix-functions/ctime.texi +++ b/doc/posix-functions/ctime.texi @@ -21,28 +21,10 @@ Likewise, POSIX says this function is obsolescent and it is planned to be removed in a future version. Portable applications can use @code{localtime_r} and @code{strftime} (or even @code{sprintf}) instead. +However, @code{localtime_r} can fail and @code{strftime} is locale dependent. @item This function may overflow its internal buffer if its argument specifies a time before the year 1000 or after the year 9999. - -Here is some history about this. -This function was safe to use decades ago when @code{time_t} was narrow -and there was no @code{strftime} or internationalization. -Code could call @code{ctime} and then select the parts needed. -For example, in Unix 7th Edition @file{/usr/src/cmd/ls.c} (1979): - -@example -cp = ctime(&p->lmtime); -if(p->lmtime < year) - printf(" %-7.7s %-4.4s ", cp+4, cp+20); else - printf(" %-12.12s ", cp+4); -@end example - -This has well-defined behavior if @code{time_t} is only 32 bits -and so was OK for circa 1979 platforms. -However, today's platforms have a @code{time_t} so wide -that the year might not be in the range [1000, 9999], -and ISO C says that in this case the behavior of @code{ctime} is undefined. @item The @code{ctime} function need not be reentrant, and consequently is not required to be thread safe. Implementations of @code{ctime} @@ -55,5 +37,31 @@ Native Windows platforms (mingw, MSVC) support only a subset of time zones supported by GNU or specified by POSIX@. @xref{tzset}. @end itemize -A more flexible function is @code{strftime}. However, note that it is -locale dependent. +Although @code{ctime} and related functions @code{asctime}, @code{asctime_r} +and @code{ctime_r} formerly were plausible to use, +they are now unsafe in general, and should be avoided. + +Decades ago when @code{time_t} was narrow +and there was no @code{strftime} or internationalization, +code could call these functions and then select the parts needed. +For example, in Unix 7th Edition @file{/usr/src/cmd/ls.c} (1979): + +@example +cp = ctime(&p->lmtime); +if(p->lmtime < year) + printf(" %-7.7s %-4.4s ", cp+4, cp+20); else + printf(" %-12.12s ", cp+4); +@end example + +@noindent +This had well-defined behavior when @code{time_t} was only 32 bits +and so was OK for circa 1979 platforms. + +However, today's platforms have a @code{time_t} so wide +that the year might not be in the range [1000, 9999]. +In this case the behavior of @code{ctime} is undefined +and some platforms behave badly, overrunning a buffer; +and even on platforms where no buffer overrun occurs, +the 7th Edition code can generate wrong output for out-of-range years, +because it incorrectly assumes that every year is represented by +exactly four digits. diff --git a/doc/posix-functions/ctime_r.texi b/doc/posix-functions/ctime_r.texi index be157cb643..8b3fcb4ea7 100644 --- a/doc/posix-functions/ctime_r.texi +++ b/doc/posix-functions/ctime_r.texi @@ -25,21 +25,9 @@ POSIX says this function is obsolescent and it is planned to be removed in a future version. Use the functions @code{localtime_r} and @code{strftime} (or even @code{sprintf}) instead. +However, @code{localtime_r} can fail and @code{strftime} is locale dependent. @item This function may overflow its output buffer if its argument specifies a time before the year 1000 or after the year 9999. @xref{ctime}. @end itemize - -@code{ctime_r} takes a pre-allocated buffer and length of the buffer, -and returns @code{NULL} on errors. -The input buffer should be at least 26 bytes in size. The output -string is locale-independent. However, years can have more than 4 -digits if @code{time_t} is sufficiently wide, so the length of the -required output buffer is not easy to determine. Increasing the -buffer size when @code{ctime_r} returns @code{NULL} is not necessarily -sufficient. The @code{NULL} return value could mean some other error -condition, which will not go away by increasing the buffer size. - -A more flexible function is @code{strftime}. However, note that it is -locale dependent.