From 16df5e8e6dccbcec52371fc569a3237e5854ba5b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 26 Mar 2019 11:02:31 +0100 Subject: [PATCH] ts: new applet Signed-off-by: Denys Vlasenko --- miscutils/ts.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 miscutils/ts.c diff --git a/miscutils/ts.c b/miscutils/ts.c new file mode 100644 index 000000000..4a02341cc --- /dev/null +++ b/miscutils/ts.c @@ -0,0 +1,88 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2006 Michael Opdenacker + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config TS +//config: bool "ts (450 bytes)" +//config: default y + +//applet:IF_TS(APPLET(ts, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TS) += ts.o + +//usage:#define ts_trivial_usage +//usage: "[-is] [STRFTIME]" +//usage:#define ts_full_usage "" + +#include "libbb.h" +#include "common_bufsiz.h" +# include + +int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ts_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + struct timespec base; + unsigned opt; + char *frac; + char *fmt_dt2str; + char *line; + + opt = getopt32(argv, "^" "is" "\0" "?1" /*max one arg*/); + if (opt) { + putenv((char*)"TZ=UTC0"); + tzset(); + } + /*argc -= optind;*/ + argv += optind; + fmt_dt2str = argv[0] ? argv[0] + : (char*)(opt ? "%b %d %H:%M:%S"+6 : "%b %d %H:%M:%S"); + frac = is_suffixed_with(fmt_dt2str, "%.S"); + if (!frac) + frac = is_suffixed_with(fmt_dt2str, "%.s"); + if (frac) { + frac++; + strcpy(frac, frac + 1); + } + +#define date_buf bb_common_bufsiz1 + setup_common_bufsiz(); + syscall(__NR_clock_gettime, CLOCK_REALTIME, &base); + + while ((line = xmalloc_fgets(stdin)) != NULL) { + struct timespec ts; + struct tm tm_time; + + /* libc has incredibly messy way of doing this, + * typically requiring -lrt. We just skip all this mess + */ + syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts); + if (opt) { + /* -i and/or -s */ + struct timespec ts1 = ts1; + if (opt & 1) /* -i */ + ts1 = ts; +//printf("%d %d\n", ts.tv_sec, base.tv_sec); + ts.tv_sec -= base.tv_sec; +//printf("%d %d\n", ts.tv_sec, base.tv_sec); + ts.tv_nsec -= base.tv_nsec; + if ((int32_t)(ts.tv_nsec) < 0) { + ts.tv_sec--; + ts.tv_nsec += 1000*1000*1000; + } + if (opt & 1) /* -i */ + base = ts1; + localtime_r(&ts.tv_sec, &tm_time); + } + strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time); + if (!frac) { + printf("%s %s", date_buf, line); + } else { + printf("%s.%06u %s", date_buf, (unsigned)ts.tv_nsec / 1000u, line); + } + free(line); + } + + return EXIT_SUCCESS; +} -- 2.25.1