From 5c677a4c6c652356f88216f3996676331f27cc08 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Wed, 24 Jun 2020 13:43:49 +0200 Subject: [PATCH] Refactor the new 'times' builtin; zero-pad seconds (re: 65d363fd) The output format is now identical to mksh's except for the locale-dependent radix point ('.' or ','). src/cmd/ksh93/bltins/misc.c: - Output format tweak: pad seconds with initial zero if < 10. - Use "too many operands" (e_toomanyops) error msg from 3ba4900e if there are operands, instead of "bad syntax" (e_badsyntax). - Consolidate repetitive calculating and printing code into print_times(). - Get rid of some excessive variables. src/cmd/ksh93/tests/builtins.sh: - Update regression tests to match the above. src/cmd/ksh93/data/builtins.c: - Update sh_opttimes[] version string. --- src/cmd/ksh93/bltins/misc.c | 59 +++++++++++---------------------- src/cmd/ksh93/data/builtins.c | 2 +- src/cmd/ksh93/tests/builtins.sh | 4 +-- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/cmd/ksh93/bltins/misc.c b/src/cmd/ksh93/bltins/misc.c index 647088c1e..28b966371 100644 --- a/src/cmd/ksh93/bltins/misc.c +++ b/src/cmd/ksh93/bltins/misc.c @@ -464,55 +464,34 @@ int b_jobs(register int n,char *argv[],Shbltin_t *context) /* * times command */ +static void print_times(clock_t uticks, clock_t sticks, Shbltin_t *context) +{ + int clk_tck = context->shp->gd->lim.clk_tck; + double utime = (double)uticks / clk_tck, stime = (double)sticks / clk_tck; + sfprintf(sfstdout, "%dm%05.2fs %dm%05.2fs\n", + (int)floor(utime / 60), fmod(utime, 60), + (int)floor(stime / 60), fmod(stime, 60)); +} int b_times(int argc, char *argv[], Shbltin_t *context) { - Shell_t *shp = context->shp; - const char *cmd = argv[0]; struct tms cpu_times; - clock_t rv; - double utime, stime, utime_min, utime_sec, stime_min, stime_sec; - - while (argc = optget(argv, sh_opttimes)) switch (argc) + /* No options or operands are supported, except --man, etc. */ + if (argc = optget(argv, sh_opttimes)) switch (argc) { case ':': errormsg(SH_DICT, 2, "%s", opt_info.arg); - break; - case '?': + errormsg(SH_DICT, ERROR_usage(2), "%s", optusage((char*)0)); + default: errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg); return(2); - default: - break; } - if (error_info.errors) - errormsg(SH_DICT, ERROR_usage(2), "%s", optusage((char*)0)); - - argv += opt_info.index; - if (*argv) - errormsg(SH_DICT, ERROR_exit(3), e_badsyntax); - - rv = times(&cpu_times); - if (rv == (clock_t)-1) - errormsg(SH_DICT, ERROR_exit(2), "times(3) failed: errno %d: %s", - errno, strerror(errno)); - - /* First line: user and system times used by the shell */ - utime = (double)cpu_times.tms_utime / shp->gd->lim.clk_tck; - utime_min = floor(utime / 60); - utime_sec = fmod(utime, 60); - stime = (double)cpu_times.tms_stime / shp->gd->lim.clk_tck; - stime_min = floor(stime / 60); - stime_sec = fmod(stime, 60); - sfprintf(sfstdout, "%dm%.2fs %dm%.2fs\n", (int)utime_min, utime_sec, (int)stime_min, stime_sec); - - /* Second line: same for the shell's child processes */ - utime = (double)cpu_times.tms_cutime / shp->gd->lim.clk_tck; - utime_min = floor(utime / 60); - utime_sec = fmod(utime, 60); - stime = (double)cpu_times.tms_cstime / shp->gd->lim.clk_tck; - stime_min = floor(stime / 60); - stime_sec = fmod(stime, 60); - sfprintf(sfstdout, "%dm%.2fs %dm%.2fs\n", (int)utime_min, utime_sec, (int)stime_min, stime_sec); - + if (argv[opt_info.index]) + errormsg(SH_DICT, ERROR_exit(2), e_toomanyops); + /* Get & print the times */ + if (times(&cpu_times) == (clock_t)-1) + errormsg(SH_DICT, ERROR_exit(1), "times(3) failed: %s", strerror(errno)); + print_times(cpu_times.tms_utime, cpu_times.tms_stime, context); + print_times(cpu_times.tms_cutime, cpu_times.tms_cstime, context); return(0); } diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c index 6947d277b..d38f2ed33 100644 --- a/src/cmd/ksh93/data/builtins.c +++ b/src/cmd/ksh93/data/builtins.c @@ -1836,7 +1836,7 @@ USAGE_LICENSE ; const char sh_opttimes[] = -"[-1c?@(#)$Id: times (ksh93) 2020-06-06 $\n]" +"[-1c?@(#)$Id: times (ksh93) 2020-06-24 $\n]" "[+NAME?times - display CPU usage by the shell and child processes]" "[+DESCRIPTION?\btimes\b displays the accumulated user and system CPU times, " "one line with the times used by the shell and another with those used by " diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh index 1ab83167e..17230d1ad 100755 --- a/src/cmd/ksh93/tests/builtins.sh +++ b/src/cmd/ksh93/tests/builtins.sh @@ -671,11 +671,11 @@ fi # ====== # 'times' builtin -expect=$'0m0.0[0-9]s 0m0.0[0-9]s\n0m0.00s 0m0.00s' +expect=$'0m00.0[0-9]s 0m00.0[0-9]s\n0m00.00s 0m00.00s' actual=$("$SHELL" -c times) [[ $actual == $expect ]] || err_exit "times output: expected $(printf %q "$expect"), got $(printf %q "$actual"))" -expect=$'*: times: incorrect syntax' +expect=$'*: times: too many operands' actual=$(set +x; eval 'times Extra Args' 2>&1) [[ $actual == $expect ]] || err_exit "times with args: expected $(printf %q "$expect"), got $(printf %q "$actual"))"