ts: new applet
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
5059653882
commit
16df5e8e6d
88
miscutils/ts.c
Normal file
88
miscutils/ts.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user