* gnulib.modules: Add nstrftime-limited, time_rz. Sort.
* src/checkpoint.c: Include <strftime.h>.
(format_checkpoint_string): Use nstrftime instead of strftime.
Also fix an obscure bug on platforms that lack tm_gmtoff+tm_zone by
calling tzalloc on those platforms; if it fails, fall back on gmtime.
Also, use fwrite instead of fprintf, since we typically know the
length already and this gives us a more-accurate byte count
in case there are partial writes.
faccessat
fchmodat
fchownat
faccessat
fchmodat
fchownat
free-posix
fseeko
fstatat
free-posix
fseeko
fstatat
full-write
futimens
gendocs
full-write
futimens
gendocs
mkdtemp
mkfifoat
modechange
mkdtemp
mkfifoat
modechange
renameat
root-uid
rpmatch
renameat
root-uid
rpmatch
safe-read
same-inode
savedir
safe-read
same-inode
savedir
stdcountof-h
stddef-h
stdint-h
stdcountof-h
stddef-h
stdint-h
strdup-posix
strerror
stringeq
strnlen
symlinkat
sys_stat-h
strdup-posix
strerror
stringeq
strnlen
symlinkat
sys_stat-h
timespec
timespec-sub
unlinkat
unlinkdir
unlocked-io
utimensat
timespec
timespec-sub
unlinkat
unlinkdir
unlocked-io
utimensat
xalignalloc
xalloc
xalloc-die
xalignalloc
xalloc
xalloc-die
#include <wordsplit.h>
#include <flexmember.h>
#include <wordsplit.h>
#include <flexmember.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <termios.h>
{
struct timespec ts = current_timespec ();
struct tm *tm = localtime (&ts.tv_sec);
{
struct timespec ts = current_timespec ();
struct tm *tm = localtime (&ts.tv_sec);
- char const *tmstr = NULL;
+#if HAVE_STRUCT_TM_TM_GMTOFF && HAVE_STRUCT_TM_TM_ZONE
+ /* struct tm has POSIX.1-2024 tm_gmtoff and tm_zone,
+ so nstrftime ignores tz and any tz value will do. */
+ timezone_t tz = 0;
+#else
+ static timezone_t tz;
+ if (tm && !tz)
+ {
+ tz = tzalloc (getenv ("TZ"));
+ if (!tz)
+ tm = NULL;
+ }
+#endif
/* Keep BUF relatively small, as any text timestamp
not fitting into BUF is likely a DoS attack. */
/* Keep BUF relatively small, as any text timestamp
not fitting into BUF is likely a DoS attack. */
- char buf[max (SYSINT_BUFSIZE, 256)];
-
- if (tm)
+ char buf[max (TIMESPEC_STRSIZE_BOUND, 256)];
+ ptrdiff_t buflen =
+ (tm
+ ? nstrftime (buf, sizeof buf, arg ? arg : "%c",
+ tm, tz, ts.tv_nsec)
+ : -1);
+ char const *tmstr;
+ idx_t tmstrlen;
+ if (buflen < 0)
+ {
+ tmstr = code_timespec (ts, buf);
+ tmstrlen = strlen (tmstr);
+ }
+ else
- buf[0] = '\0';
- char const *fmt = arg ? arg : "%c";
- if (strftime (buf, sizeof buf, fmt, tm) != 0 || !buf[0])
- tmstr = buf;
+ tmstr = buf;
+ tmstrlen = buflen;
- if (!tmstr)
- tmstr = timetostr (ts.tv_sec, buf);
- len = add_printf (len, fprintf (fp, "%s", tmstr));
+ len = add_printf (len, fwrite (tmstr, 1, tmstrlen, stdout));