busybox/miscutils/ts.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Copyright (C) 2019 Denys Vlasenko <vda.linux@googlemail.com>
   4 * Licensed under GPLv2, see file LICENSE in this source tree.
   5 */
   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]"
  16//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"
  20
  21#include "libbb.h"
  22#include "common_bufsiz.h"
  23
  24int ts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  25int ts_main(int argc UNUSED_PARAM, char **argv)
  26{
  27        struct timeval base;
  28        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++;
  47                frac[0] = frac[1];
  48                frac[1] = '\0';
  49        }
  50
  51#define date_buf bb_common_bufsiz1
  52        setup_common_bufsiz();
  53        xgettimeofday(&base);
  54
  55        while ((line = xmalloc_fgets(stdin)) != NULL) {
  56                struct timeval ts;
  57                struct tm tm_time;
  58
  59                xgettimeofday(&ts);
  60                if (opt) {
  61                        /* -i and/or -s */
  62                        struct timeval ts1 = ts1;
  63                        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);
  68                        ts.tv_usec -= base.tv_usec;
  69                        if ((int32_t)(ts.tv_usec) < 0) {
  70                                ts.tv_sec--;
  71                                ts.tv_usec += 1000*1000;
  72                        }
  73                        if (opt & 1) /* -i */
  74                                base = ts1;
  75                }
  76                localtime_r(&ts.tv_sec, &tm_time);
  77                strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time);
  78                if (!frac) {
  79                        printf("%s %s", date_buf, line);
  80                } else {
  81                        printf("%s.%06u %s", date_buf, (unsigned)ts.tv_usec, line);
  82                }
  83                free(line);
  84        }
  85
  86        return EXIT_SUCCESS;
  87}
  88