diff options
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/ts.c | 88 |
1 files changed, 88 insertions, 0 deletions
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 <michael@free-electrons.com> + * + * 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 <sys/syscall.h> + +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; +} |