From 3c13da3dab539eac948de48640d8862857d0c8d0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Dec 2020 23:48:01 +0100 Subject: [PATCH] libbb: introduce and use xgettimeofday(), do not truncate 64-bit time_t in shells function old new delta xgettimeofday - 11 +11 get_local_var_value 280 281 +1 svlogd_main 1323 1322 -1 change_epoch 67 66 -1 timestamp_and_log 461 458 -3 hwclock_main 301 298 -3 fmt_time_bernstein_25 135 132 -3 step_time 331 326 -5 script_main 1207 1202 -5 machtime 34 28 -6 curtime 61 54 -7 ts_main 423 415 -8 nmeter_main 761 751 -10 gettime1900d 67 46 -21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/12 up/down: 12/-73) Total: -61 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/time.c | 6 +++--- libbb/xfuncs_printf.c | 11 +++++++++++ miscutils/ts.c | 4 ++-- networking/inetd.c | 2 +- networking/ntpd.c | 4 ++-- networking/traceroute.c | 2 +- procps/nmeter.c | 8 ++++---- runit/runsv.c | 4 ++-- runit/svlogd.c | 4 ++-- shell/ash.c | 10 +++++----- shell/hush.c | 10 +++++----- sysklogd/syslogd.c | 2 +- util-linux/hwclock.c | 8 ++++---- util-linux/mdev.c | 2 +- util-linux/script.c | 2 +- 16 files changed, 46 insertions(+), 34 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index cae54658b..dad6fc687 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -657,6 +657,7 @@ void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC; time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC; char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; +void xgettimeofday(struct timeval *tv) FAST_FUNC; void xsettimeofday(const struct timeval *tv) FAST_FUNC; diff --git a/libbb/time.c b/libbb/time.c index 74a69eefb..cf5f2e5c8 100644 --- a/libbb/time.c +++ b/libbb/time.c @@ -291,19 +291,19 @@ unsigned FAST_FUNC monotonic_sec(void) unsigned long long FAST_FUNC monotonic_ns(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; } unsigned long long FAST_FUNC monotonic_us(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000000ULL + tv.tv_usec; } unsigned long long FAST_FUNC monotonic_ms(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return tv.tv_sec * 1000ULL + tv.tv_usec / 1000; } unsigned FAST_FUNC monotonic_sec(void) diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index aea995a5c..99596b9d0 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -720,3 +720,14 @@ void FAST_FUNC xsettimeofday(const struct timeval *tv) if (settimeofday(tv, NULL)) bb_simple_perror_msg_and_die("settimeofday"); } + +void FAST_FUNC xgettimeofday(struct timeval *tv) +{ +#if 0 + if (gettimeofday(tv, NULL)) + bb_simple_perror_msg_and_die("gettimeofday"); +#else + /* Never fails on Linux */ + gettimeofday(tv, NULL); +#endif +} diff --git a/miscutils/ts.c b/miscutils/ts.c index f2d367654..6e5d77bda 100644 --- a/miscutils/ts.c +++ b/miscutils/ts.c @@ -47,13 +47,13 @@ int ts_main(int argc UNUSED_PARAM, char **argv) #define date_buf bb_common_bufsiz1 setup_common_bufsiz(); - gettimeofday(&base, NULL); + xgettimeofday(&base); while ((line = xmalloc_fgets(stdin)) != NULL) { struct timeval ts; struct tm tm_time; - gettimeofday(&ts, NULL); + xgettimeofday(&ts); if (opt) { /* -i and/or -s */ struct timeval ts1 = ts1; diff --git a/networking/inetd.c b/networking/inetd.c index 9f5a436d6..febfb7b73 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1701,7 +1701,7 @@ static uint32_t machtime(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); return htonl((uint32_t)(tv.tv_sec + 2208988800U)); } /* ARGSUSED */ diff --git a/networking/ntpd.c b/networking/ntpd.c index 5a540a391..46d8f3495 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -560,7 +560,7 @@ static double gettime1900d(void) { struct timeval tv; - gettimeofday(&tv, NULL); /* never fails */ + xgettimeofday(&tv); G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970; return G.cur_time; } @@ -1144,7 +1144,7 @@ step_time(double offset) char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4]; time_t tval; - gettimeofday(&tvc, NULL); /* never fails */ + xgettimeofday(&tvc); dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; d_to_tv(dtime, &tvn); xsettimeofday(&tvn); diff --git a/networking/traceroute.c b/networking/traceroute.c index 3f1a9ab46..bd63e4449 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -505,7 +505,7 @@ send_probe(int seq, int ttl) struct outdata6_t *pkt = (void *) outdata; pkt->ident6 = ident; pkt->seq6 = htonl(seq); - /*gettimeofday(&pkt->tv, &tz);*/ + /*xgettimeofday(&pkt->tv);*/ icp = outicmp6; } else #endif diff --git a/procps/nmeter.c b/procps/nmeter.c index 07b7abe2f..f08938654 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -952,11 +952,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) reset_outbuf(); if (G.delta >= 0) { - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz); } - gettimeofday(&G.start, NULL); + xgettimeofday(&G.start); G.tv = G.start; while (1) { collect_info(first); @@ -971,7 +971,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) if (G.delta >= 0) { int rem; // can be commented out, will sacrifice sleep time precision a bit - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); if (need_seconds) rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz; else @@ -983,7 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) } usleep(rem); } - gettimeofday(&G.tv, NULL); + xgettimeofday(&G.tv); } /*return 0;*/ diff --git a/runit/runsv.c b/runit/runsv.c index d395d4528..ecab8cdf5 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -62,12 +62,12 @@ static void gettimeofday_ns(struct timespec *ts) && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) ) { /* Cheat */ - gettimeofday((void*)ts, NULL); + xgettimeofday((void*)ts); ts->tv_nsec *= 1000; } else { /* For example, musl has "incompatible" layouts */ struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } diff --git a/runit/svlogd.c b/runit/svlogd.c index 040e71104..294e31aca 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -351,7 +351,7 @@ static void fmt_time_human_30nul(char *s, char dt_delim) struct tm *ptm; struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); ptm = gmtime_r(&tv.tv_sec, &tm); /* ^^^ using gmtime_r() instead of gmtime() to not use static data */ sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000", @@ -376,7 +376,7 @@ static void fmt_time_bernstein_25(char *s) struct timeval tv; unsigned sec_hi; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32; tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec; tv.tv_usec *= 1000; diff --git a/shell/ash.c b/shell/ash.c index f16d7fb6a..54f004375 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -11371,10 +11371,10 @@ static void FAST_FUNC change_epoch(struct var *vepoch, const char *fmt) { struct timeval tv; - char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3]; + char buffer[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; - gettimeofday(&tv, NULL); - sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec); + xgettimeofday(&tv); + sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); setvar(vepoch->var_text, buffer, VNOFUNC); vepoch->flags &= ~VNOFUNC; } @@ -11382,13 +11382,13 @@ change_epoch(struct var *vepoch, const char *fmt) static void FAST_FUNC change_seconds(const char *value UNUSED_PARAM) { - change_epoch(&vepochs, "%lu"); + change_epoch(&vepochs, "%llu"); } static void FAST_FUNC change_realtime(const char *value UNUSED_PARAM) { - change_epoch(&vepochr, "%lu.%06u"); + change_epoch(&vepochr, "%llu.%06u"); } #endif diff --git a/shell/hush.c b/shell/hush.c index 9fead37da..65f08659f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1027,7 +1027,7 @@ struct globals { struct sigaction sa; char optstring_buf[sizeof("eixcs")]; #if BASH_EPOCH_VARS - char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; + char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3]; #endif #if ENABLE_FEATURE_EDITING char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN]; @@ -2277,13 +2277,13 @@ static const char* FAST_FUNC get_local_var_value(const char *name) { const char *fmt = NULL; if (strcmp(name, "EPOCHSECONDS") == 0) - fmt = "%lu"; + fmt = "%llu"; else if (strcmp(name, "EPOCHREALTIME") == 0) - fmt = "%lu.%06u"; + fmt = "%llu.%06u"; if (fmt) { struct timeval tv; - gettimeofday(&tv, NULL); - sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec, + xgettimeofday(&tv); + sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); return G.epoch_buf; } diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 598f28d0c..6ddfd771a 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -842,7 +842,7 @@ static void timestamp_and_log(int pri, char *msg, int len) #if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS if (!timestamp) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); now = tv.tv_sec; timestamp = ctime(&now) + 4; /* skip day of week */ /* overwrite year by milliseconds, zero terminate */ diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 25db7cdad..723b09589 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -79,7 +79,7 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc) int before = tm_time.tm_sec; while (1) { rtc_read_tm(&tm_time, fd); - gettimeofday(sys_tv, NULL); + xgettimeofday(sys_tv); if (before != (int)tm_time.tm_sec) break; } @@ -205,7 +205,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) int rtc; rtc = rtc_xopen(pp_rtcname, O_WRONLY); - gettimeofday(&tv, NULL); + xgettimeofday(&tv); /* Prepare tm_time */ if (sizeof(time_t) == sizeof(tv.tv_sec)) { if (utc) @@ -253,7 +253,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) unsigned rem_usec; time_t t; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); t = tv.tv_sec; rem_usec = 1000000 - tv.tv_usec; @@ -274,7 +274,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) } /* gmtime/localtime took some time, re-get cur time */ - gettimeofday(&tv, NULL); + xgettimeofday(&tv); if (tv.tv_sec < t /* we are still in old second */ || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */ diff --git a/util-linux/mdev.c b/util-linux/mdev.c index ebf83d1a3..dbbcbc655 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -963,7 +963,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path) static char *curtime(void) { struct timeval tv; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); sprintf( strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec), ".%06u", diff --git a/util-linux/script.c b/util-linux/script.c index 4eac5e94f..963435335 100644 --- a/util-linux/script.c +++ b/util-linux/script.c @@ -172,7 +172,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) struct timeval tv; double newtime; - gettimeofday(&tv, NULL); + xgettimeofday(&tv); newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; fprintf(timing_fp, "%f %u\n", newtime - oldtime, count); oldtime = newtime;