#include <wordsplit.h>
#include <flexmember.h>
+#include <strftime.h>
#include <sys/ioctl.h>
#include <termios.h>
{
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. */
- 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));
}
break;