-/* $OpenBSD: ts.c,v 1.9 2022/08/03 16:54:30 job Exp $ */
+/* $OpenBSD: ts.c,v 1.10 2022/09/01 00:14:36 cheloha Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@openbsd.org>
* Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/time.h>
#include <err.h>
#include <unistd.h>
#include <time.h>
+SIMPLEQ_HEAD(, usec) usec_queue = SIMPLEQ_HEAD_INITIALIZER(usec_queue);
+struct usec {
+ SIMPLEQ_ENTRY(usec) next;
+ char *pos;
+};
+
static char *format = "%b %d %H:%M:%S";
static char *buf;
static char *outbuf;
static size_t bufsize;
static size_t obsize;
-static void fmtfmt(const struct timespec *);
+static void fmtfmt(void);
+static void fmtprint(const struct timespec *);
static void __dead usage(void);
int
if ((outbuf = calloc(1, obsize)) == NULL)
err(1, NULL);
+ fmtfmt();
+
/* force UTC for interval calculations */
if (iflag || sflag)
if (setenv("TZ", "UTC", 1) == -1)
timespecadd(&now, &utc_offset, &ts);
else
ts = now;
- fmtfmt(&ts);
+ fmtprint(&ts);
if (iflag)
start = now;
}
* so you can format while you format
*/
static void
-fmtfmt(const struct timespec *ts)
+fmtfmt(void)
{
- struct tm *tm;
- char *f, us[7];
+ char *f;
+ struct usec *u;
- if ((tm = localtime(&ts->tv_sec)) == NULL)
- err(1, "localtime");
-
- snprintf(us, sizeof(us), "%06ld", ts->tv_nsec / 1000);
strlcpy(buf, format, bufsize);
f = buf;
f[0] = f[1];
f[1] = '.';
f += 2;
+ u = malloc(sizeof u);
+ if (u == NULL)
+ err(1, NULL);
+ u->pos = f;
+ SIMPLEQ_INSERT_TAIL(&usec_queue, u, next);
l = strlen(f);
memmove(f + 6, f, l + 1);
- memcpy(f, us, 6);
f += 6;
}
} while (*f != '\0');
+}
+
+static void
+fmtprint(const struct timespec *ts)
+{
+ char us[8];
+ struct tm *tm;
+ struct usec *u;
+
+ if ((tm = localtime(&ts->tv_sec)) == NULL)
+ err(1, "localtime");
+
+ /* Update any microsecond substrings in the format buffer. */
+ if (!SIMPLEQ_EMPTY(&usec_queue)) {
+ snprintf(us, sizeof(us), "%06ld", ts->tv_nsec / 1000);
+ SIMPLEQ_FOREACH(u, &usec_queue, next)
+ memcpy(u->pos, us, 6);
+ }
*outbuf = '\0';
if (*buf != '\0') {