mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 03:32:24 +00:00
Now that we have an iffe feature test for getrusage(3), introduced
in 70fc1da7
, the millisecond-precision 'times' command from the
last version of ksh2020 can easily be backported.
src/cmd/ksh93/bltins/misc.c:
- Incorporate ksh2020 'times' command, with a couple of tweaks:
* Use locale's radix point instead of '.'.
* Pad seconds with initial zero if < 10.
src/cmd/ksh93/data/builtins.c:
- Update version date for 'times --man'.
src/cmd/ksh93/tests/builtins.sh:
- Update 'times' test for 3 digits after radix point.
This commit is contained in:
parent
c5820aabc9
commit
b1a4131123
4 changed files with 59 additions and 13 deletions
3
NEWS
3
NEWS
|
@ -7,6 +7,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
|||
|
||||
- Fixed a bug that caused 'set -b' to have no effect.
|
||||
|
||||
- Following the 'time' keyword, the 'times' builtin command now also
|
||||
supports millisecond precision.
|
||||
|
||||
2020-07-13:
|
||||
|
||||
- Fixed a fork bomb that could occur when the vi editor was sent SIGTSTP
|
||||
|
|
|
@ -47,7 +47,13 @@
|
|||
#include "jobs.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "FEATURE/locale"
|
||||
#include "FEATURE/time"
|
||||
#if _lib_getrusage
|
||||
#include <sys/resource.h>
|
||||
#else
|
||||
#include <times.h>
|
||||
#endif
|
||||
|
||||
#define DOTMAX MAXDEPTH /* maximum level of . nesting */
|
||||
|
||||
|
@ -464,17 +470,57 @@ 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)
|
||||
static void print_times(struct timeval utime, struct timeval stime)
|
||||
{
|
||||
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 ut_min = utime.tv_sec / 60;
|
||||
int ut_sec = utime.tv_sec % 60;
|
||||
int ut_ms = utime.tv_usec / 1000;
|
||||
int st_min = stime.tv_sec / 60;
|
||||
int st_sec = stime.tv_sec % 60;
|
||||
int st_ms = stime.tv_usec / 1000;
|
||||
char radix = GETDECIMAL(0);
|
||||
sfprintf(sfstdout, "%dm%02d%c%03ds %dm%02d%c%03ds\n", ut_min, ut_sec, radix, ut_ms, st_min, st_sec, radix, st_ms);
|
||||
}
|
||||
#if _lib_getrusage
|
||||
static void print_cpu_times()
|
||||
{
|
||||
struct rusage usage;
|
||||
/* Print the time (user & system) consumed by the shell. */
|
||||
getrusage(RUSAGE_SELF, &usage);
|
||||
print_times(usage.ru_utime, usage.ru_stime);
|
||||
/* Print the time (user & system) consumed by the child processes of the shell. */
|
||||
getrusage(RUSAGE_CHILDREN, &usage);
|
||||
print_times(usage.ru_utime, usage.ru_stime);
|
||||
}
|
||||
#else /* _lib_getrusage */
|
||||
static void print_cpu_times()
|
||||
{
|
||||
struct timeval utime, stime;
|
||||
double dtime;
|
||||
int clk_tck = shgd->lim.clk_tck;
|
||||
struct tms cpu_times;
|
||||
times(&cpu_times);
|
||||
/* Print the time (user & system) consumed by the shell. */
|
||||
dtime = (double)cpu_times.tms_utime / clk_tck;
|
||||
utime.tv_sec = dtime / 60;
|
||||
utime.tv_usec = 1000000 * (dtime - utime.tv_sec);
|
||||
dtime = (double)cpu_times.tms_stime / clk_tck;
|
||||
stime.tv_sec = dtime / 60;
|
||||
stime.tv_usec = 1000000 * (dtime - utime.tv_sec);
|
||||
print_times(utime, stime);
|
||||
/* Print the time (user & system) consumed by the child processes of the shell. */
|
||||
dtime = (double)cpu_times.tms_cutime / clk_tck;
|
||||
utime.tv_sec = dtime / 60;
|
||||
utime.tv_usec = 1000000 * (dtime - utime.tv_sec);
|
||||
dtime = (double)cpu_times.tms_cstime / clk_tck;
|
||||
stime.tv_sec = dtime / 60;
|
||||
stime.tv_usec = 1000000 * (dtime - utime.tv_sec);
|
||||
print_times(utime, stime);
|
||||
}
|
||||
#endif /* _lib_getrusage */
|
||||
int b_times(int argc, char *argv[], Shbltin_t *context)
|
||||
{
|
||||
struct tms cpu_times;
|
||||
NOT_USED(context);
|
||||
/* No options or operands are supported, except --man, etc. */
|
||||
if (argc = optget(argv, sh_opttimes)) switch (argc)
|
||||
{
|
||||
|
@ -488,10 +534,7 @@ int b_times(int argc, char *argv[], Shbltin_t *context)
|
|||
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);
|
||||
print_cpu_times();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1906,7 +1906,7 @@ USAGE_LICENSE
|
|||
;
|
||||
|
||||
const char sh_opttimes[] =
|
||||
"[-1c?@(#)$Id: times (ksh93) 2020-06-24 $\n]"
|
||||
"[-1c?@(#)$Id: times (ksh93) 2020-07-14 $\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 "
|
||||
|
|
|
@ -700,7 +700,7 @@ fi
|
|||
# ======
|
||||
# 'times' builtin
|
||||
|
||||
expect=$'0m00.0[0-9]s 0m00.0[0-9]s\n0m00.00s 0m00.00s'
|
||||
expect=$'0m00.0[0-9][0-9]s 0m00.0[0-9][0-9]s\n0m00.000s 0m00.000s'
|
||||
actual=$("$SHELL" -c times)
|
||||
[[ $actual == $expect ]] || err_exit "times output: expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
|
|
Loading…
Reference in a new issue