libfaketime allows for easy testing of this bug: LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 FAKETIME='-1y' \ FAKETIME_START_AFTER_SECONDS=1 TIMEFORMAT=%lR /bin/bash -c 'time sleep 2' --- execute_cmd.c | 24 ++++++++++++++++++++---- lib/sh/timeval.c | 5 ----- 2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/execute_cmd.c b/execute_cmd.c index f9a755d..d3cb93b 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -1081,7 +1081,12 @@ extern int timeval_to_cpu __P((struct timeval *, struct timeval *, struct timeva static const int precs[] = { 0, 100, 10, 1 }; -/* Expand one `%'-prefixed escape sequence from a time format string. */ +/* Expand one `%'-prefixed escape sequence from a time format string, + buf is the buffer where we are writing the timestamp, prec is the + precision (number of decimal places after the .), lng a boolean + stating that the time should be shown in minutes and seconds instead + of only seconds, and (rs, rsf) are the seconds and milliseconds ellapsed. + */ static int mkfmt (buf, prec, lng, sec, sec_fraction) char *buf; @@ -1090,12 +1095,23 @@ mkfmt (buf, prec, lng, sec, sec_fraction) int sec_fraction; { time_t min; - char abuf[INT_STRLEN_BOUND(time_t) + 1]; + char abuf[INT_STRLEN_BOUND(time_t) + 2]; int ind, aind; ind = 0; abuf[sizeof(abuf) - 1] = '\0'; + if (sec < 0) + { + buf[ind++] = '-'; + sec = -sec; + if (sec_fraction > 0) + { + sec_fraction = 1000 - sec_fraction; + sec--; + } + } + /* If LNG is non-zero, we want to decompose SEC into minutes and seconds. */ if (lng) { @@ -1156,7 +1172,7 @@ mkfmt (buf, prec, lng, sec, sec_fraction) An occurrence of `%%' in the format string is translated to a `%'. The result is printed to FP, a pointer to a FILE. The other variables are the seconds and thousandths of a second of real, user, and system time, - resectively. */ + respectively. */ static void print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu) FILE *fp; @@ -1169,7 +1185,7 @@ print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu) int ssf, cpu; { int prec, lng, len; - char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("mSS.FFFF")]; + char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("-mSS.FFFF")]; time_t sum; int sum_frac; int sindex, ssize; diff --git a/lib/sh/timeval.c b/lib/sh/timeval.c index 7bd9df8..8351687 100644 --- a/lib/sh/timeval.c +++ b/lib/sh/timeval.c @@ -37,11 +37,6 @@ difftimeval (d, t1, t2) { d->tv_usec += 1000000; d->tv_sec -= 1; - if (d->tv_sec < 0) /* ??? -- BSD/OS does this */ - { - d->tv_sec = 0; - d->tv_usec = 0; - } } return d; } -- 2.0.3