blob: c7e477cc5bd0ab13f4eb54c9abee1fb765b17d35 [file] [log] [blame]
Denys Vlasenko16df5e82019-03-26 11:02:31 +01001/* vi: set sw=4 ts=4: */
2/*
Denys Vlasenkof370a662019-03-26 11:12:15 +01003 * Copyright (C) 2019 Denys Vlasenko <vda.linux@googlemail.com>
4 * Licensed under GPLv2, see file LICENSE in this source tree.
Denys Vlasenko16df5e82019-03-26 11:02:31 +01005 */
6//config:config TS
7//config: bool "ts (450 bytes)"
8//config: default y
9
10//applet:IF_TS(APPLET(ts, BB_DIR_USR_BIN, BB_SUID_DROP))
11
12//kbuild:lib-$(CONFIG_TS) += ts.o
13
14//usage:#define ts_trivial_usage
15//usage: "[-is] [STRFTIME]"
Denys Vlasenko18492852021-06-13 03:12:09 +020016//usage:#define ts_full_usage "\n\n"
17//usage: "Pipe stdin to stdout, add timestamp to each line\n"
18//usage: "\n -s Time since start"
19//usage: "\n -i Time since previous line"
Denys Vlasenko16df5e82019-03-26 11:02:31 +010020
21#include "libbb.h"
22#include "common_bufsiz.h"
Denys Vlasenko16df5e82019-03-26 11:02:31 +010023
24int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denys Vlasenkof370a662019-03-26 11:12:15 +010025int ts_main(int argc UNUSED_PARAM, char **argv)
Denys Vlasenko16df5e82019-03-26 11:02:31 +010026{
Denys Vlasenko973698d2019-03-26 11:44:48 +010027 struct timeval base;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010028 unsigned opt;
29 char *frac;
30 char *fmt_dt2str;
31 char *line;
32
33 opt = getopt32(argv, "^" "is" "\0" "?1" /*max one arg*/);
34 if (opt) {
35 putenv((char*)"TZ=UTC0");
36 tzset();
37 }
38 /*argc -= optind;*/
39 argv += optind;
40 fmt_dt2str = argv[0] ? argv[0]
41 : (char*)(opt ? "%b %d %H:%M:%S"+6 : "%b %d %H:%M:%S");
42 frac = is_suffixed_with(fmt_dt2str, "%.S");
43 if (!frac)
44 frac = is_suffixed_with(fmt_dt2str, "%.s");
45 if (frac) {
46 frac++;
Denys Vlasenko3395e2a2019-03-26 11:41:35 +010047 frac[0] = frac[1];
48 frac[1] = '\0';
Denys Vlasenko16df5e82019-03-26 11:02:31 +010049 }
50
51#define date_buf bb_common_bufsiz1
52 setup_common_bufsiz();
Denys Vlasenko3c13da32020-12-30 23:48:01 +010053 xgettimeofday(&base);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010054
55 while ((line = xmalloc_fgets(stdin)) != NULL) {
Denys Vlasenko973698d2019-03-26 11:44:48 +010056 struct timeval ts;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010057 struct tm tm_time;
58
Denys Vlasenko3c13da32020-12-30 23:48:01 +010059 xgettimeofday(&ts);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010060 if (opt) {
61 /* -i and/or -s */
Denys Vlasenko973698d2019-03-26 11:44:48 +010062 struct timeval ts1 = ts1;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010063 if (opt & 1) /* -i */
64 ts1 = ts;
65//printf("%d %d\n", ts.tv_sec, base.tv_sec);
66 ts.tv_sec -= base.tv_sec;
67//printf("%d %d\n", ts.tv_sec, base.tv_sec);
Denys Vlasenko973698d2019-03-26 11:44:48 +010068 ts.tv_usec -= base.tv_usec;
69 if ((int32_t)(ts.tv_usec) < 0) {
Denys Vlasenko16df5e82019-03-26 11:02:31 +010070 ts.tv_sec--;
Denys Vlasenko973698d2019-03-26 11:44:48 +010071 ts.tv_usec += 1000*1000;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010072 }
73 if (opt & 1) /* -i */
74 base = ts1;
Denys Vlasenko16df5e82019-03-26 11:02:31 +010075 }
Denys Vlasenkofe78c9a2019-03-26 11:51:21 +010076 localtime_r(&ts.tv_sec, &tm_time);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010077 strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time);
78 if (!frac) {
79 printf("%s %s", date_buf, line);
80 } else {
Denys Vlasenko973698d2019-03-26 11:44:48 +010081 printf("%s.%06u %s", date_buf, (unsigned)ts.tv_usec, line);
Denys Vlasenko16df5e82019-03-26 11:02:31 +010082 }
83 free(line);
84 }
85
86 return EXIT_SUCCESS;
87}