[hackers] [sbase][PATCH] Add implementation of ts(1)

From: Elie Le Vaillant <eolien55_AT_disroot.org>
Date: Sun, 25 Feb 2024 19:35:54 +0100

The -m flag is not compliant to either the OpenBSD or the moreutils
implementation of ts(1), but closer to the toybox one. It allows
the user to add in nanoseconds, like toybox, but allows to specify
how many digits are printed.
---
 .gitignore |  1 +
 Makefile   |  1 +
 README     |  1 +
 ts.1       | 38 +++++++++++++++++++++++
 ts.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 132 insertions(+)
 create mode 100644 ts.1
 create mode 100644 ts.c
diff --git a/.gitignore b/.gitignore
index e591886..001b055 100644
--- a/.gitignore
+++ b/.gitignore
_AT_@ -88,6 +88,7 @@
 /touch
 /tr
 /true
+/ts
 /tsort
 /tty
 /uname
diff --git a/Makefile b/Makefile
index 55e00d9..7bd9626 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -177,6 +177,7 @@ BIN =\
 	touch\
 	tr\
 	true\
+	ts\
 	tsort\
 	tty\
 	uname\
diff --git a/README b/README
index 91a60f9..5555f8b 100644
--- a/README
+++ b/README
_AT_@ -129,6 +129,7 @@ The following tools are implemented:
 0=*|o touch           .
 0#*|o tr              .
 0=*|o true            .
+0=* x ts              .
 0=* o tsort           .
 0=*|o tty             .
 0=*|o uname           .
diff --git a/ts.1 b/ts.1
new file mode 100644
index 0000000..dcc04ac
--- /dev/null
+++ b/ts.1
_AT_@ -0,0 +1,38 @@
+.Dd 2024-02-25
+.Dt TS 1
+.Os sbase
+.Sh NAME
+.Nm ts
+.Nd timestamp input
+.Sh SYNOPSIS
+.Nm
+.Op Fl i | Fl s
+.Op Fl m Ar n
+.Op Ar format
+.Sh DESCRIPTION
+.Nm
+prepends a timestamp to each line of standard input and
+writes it to standard output.
+The timestamp is formatted using
+.Ar format ,
+according to the conversion specifications described in
+.Xf strftime 3 .
+The default format is "%b %d %H:%M:%S"; or "%H:%M:%S"
+if one of the
+.Fl i
+or
+.Fl s
+options is used.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl i
+Display time elapsed since the last timestamp.
+.It Fl m
+Append to the timestamp
+.Ar n
+digits (up to 9) of nanoseconds.
+.It Fl s
+Display time elapsed since the start of the program.
+.El
+.Sh SEE ALSO
+.Xr strftime 3
diff --git a/ts.c b/ts.c
new file mode 100644
index 0000000..d419660
--- /dev/null
+++ b/ts.c
_AT_@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "util.h"
+
+#define	timespecsub(tsp, usp, vsp)					\
+	do {								\
+		(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;		\
+		(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec;	\
+		if ((vsp)->tv_nsec < 0) {				\
+			(vsp)->tv_sec--;				\
+			(vsp)->tv_nsec += 1000000000L;			\
+		}							\
+	} while (0)
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [-i | -s] [-m] [format]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int iflag, mflag, sflag, div;
+	ssize_t len;
+	size_t n;
+	char *fmt, *line = NULL, buf[256], mm[11];
+	struct tm *tm;
+	struct timespec start, now, ts;
+	clockid_t clock = CLOCK_REALTIME;
+
+	fmt = "%b %d %H:%M:%S";
+	*mm = '\0';
+	iflag = mflag = sflag = 0;
+
+	ARGBEGIN {
+	case 'i':
+		iflag = 1;
+		fmt = "%H:%M:%S";
+		clock = CLOCK_MONOTONIC;
+		break;
+	case 'm':
+		mflag = estrtonum(EARGF(usage()), 1, 9);
+		break;
+	case 's':
+		sflag = 1;
+		fmt = "%H:%M:%S";
+		clock = CLOCK_MONOTONIC;
+		break;
+	default:
+		usage();
+	} ARGEND
+
+	/* divisor factor for nanosecs */
+	div = 1000000000;
+	for (int i = mflag; i > 0; i--)
+		div /= 10;
+
+	setvbuf(stdout, NULL, _IOLBF, 0);
+
+	clock_gettime(clock, &start);
+
+	if (argc > 1)
+		usage();
+	else if (argc == 1)
+		fmt = *argv;
+
+	while ((len = getline(&line, &n, stdin)) > 0) {
+		clock_gettime(clock, &now);
+		if (iflag || sflag)
+			timespecsub(&now, &start, &ts);
+		else
+			ts = now;
+		if (mflag)
+			sprintf(mm, ".%0*ld", mflag, ts.tv_nsec/div);
+
+		tm = (iflag || sflag) ? gmtime(&ts.tv_sec) : localtime(&ts.tv_sec);
+
+		strftime(buf, sizeof(buf), fmt, tm);
+		printf("%s%s ", buf, mm);
+		fwrite(line, 1, len, stdout);
+
+		if (iflag)
+			start = now;
+	}
+	free(line);
+
+	return 0;
+}
-- 
2.43.0
Received on Sun Feb 25 2024 - 19:35:54 CET

This archive was generated by hypermail 2.3.0 : Mon Feb 26 2024 - 23:48:38 CET