Bug in times builtin
diff mbox series

Message ID m2r281wn3m.fsf@pomona.edu
State New
Headers show
Series
  • Bug in times builtin
Related show

Commit Message

Michael Greenberg June 10, 2019, 2:07 p.m. UTC
Hi all,

The `times` builtin in dash fails to compute the seconds part
properly. To see the bug, I ran the following script:

```sh
delay() {
    case "$#" in
        ( 0 ) secs=1 ;;
        ( 1 ) secs=$(($1+0)) ;;
        ( * ) exit 2 ;;
    esac

    start=$(date "+%s")
    while now=$(date "+%s") ;
          [ $((now - start)) -lt "$secs" ]
    do
        :
    done
}

times
delay $((5 * 60))
times
```

The script implements a 5min sleep. An unpatched dash produces the
following output:

```
0m0.000000s 0m0.000000s
0m0.000000s 0m0.000000s
0m8.330000s 0m26.690000s
1m97.670000s 1m107.150000s
```

With the patch, the seconds are computed correctly (NB that this is a
different run so times vary slightly):

```
0m0.000000s 0m0.000000s
0m0.000000s 0m0.000000s
0m8.260000s 0m27.050000s
1m38.130000s 1m45.960000s
```

If folks are opposed to including math.h for some reason, I'm sure the
computation could be done another way.

Cheers,
Michael

Signed-off-by: Michael Greenberg <michael.greenberg@pomona.edu>

Patch
diff mbox series

diff --git a/src/bltin/times.c b/src/bltin/times.c
index 8eabc1f..7e66f90 100644
--- a/src/bltin/times.c
+++ b/src/bltin/times.c
@@ -3,6 +3,7 @@ 
  * This file contains code for the times builtin.
  */
 
+#include <math.h>
 #include <sys/times.h>
 #include <unistd.h>
 #ifdef USE_GLIBC_STDIO
@@ -19,12 +20,12 @@  int timescmd() {
 	times(&buf);
 	printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
 	       (int) (buf.tms_utime / clk_tck / 60),
-	       ((double) buf.tms_utime) / clk_tck,
+	       fmod(((double) buf.tms_utime) / clk_tck, 60),
 	       (int) (buf.tms_stime / clk_tck / 60),
-	       ((double) buf.tms_stime) / clk_tck,
+	       fmod(((double) buf.tms_stime) / clk_tck, 60),
 	       (int) (buf.tms_cutime / clk_tck / 60),
-	       ((double) buf.tms_cutime) / clk_tck,
+	       fmod(((double) buf.tms_cutime) / clk_tck, 60),
 	       (int) (buf.tms_cstime / clk_tck / 60),
-	       ((double) buf.tms_cstime) / clk_tck);
+	       fmod(((double) buf.tms_cstime) / clk_tck, 60));
 	return 0;
 }