Index: usr.bin/time/time.1 =================================================================== --- usr.bin/time/time.1 (revision 286222) +++ usr.bin/time/time.1 (working copy) @@ -36,7 +36,7 @@ .Nd time command execution .Sh SYNOPSIS .Nm -.Op Fl al +.Op Fl acl .Op Fl h | Fl p .Op Fl o Ar file .Ar utility Op Ar argument ... @@ -66,6 +66,9 @@ flag is used, append to the specified file rather than overwriting it. Otherwise, this option has no effect. +.It Fl c +Print time in a format that is equal to the time output of +.Xr csh 1 .It Fl h Print times in a human friendly format. Times are printed in minutes, hours, Index: usr.bin/time/time.c =================================================================== --- usr.bin/time/time.c (revision 286222) +++ usr.bin/time/time.c (working copy) @@ -65,14 +65,14 @@ static void siginfo(int); static void usage(void); -static char decimal_point; +static char decimal_point, colon; static struct timeval before_tv; -static int hflag, pflag; +static int aflag, cflag, hflag, lflag, pflag; int main(int argc, char **argv) { - int aflag, ch, lflag, status; + int ch, status; int exitonsig; pid_t pid; struct rlimit rl; @@ -80,16 +80,23 @@ struct timeval after; char *ofn = NULL; FILE *out = stderr; + int hz; + u_long ticks; + (void) setlocale(LC_NUMERIC, ""); decimal_point = localeconv()->decimal_point[0]; + colon = ':'; - aflag = hflag = lflag = pflag = 0; - while ((ch = getopt(argc, argv, "ahlo:p")) != -1) + aflag = cflag = hflag = lflag = pflag = 0; + while ((ch = getopt(argc, argv, "achlo:p")) != -1) switch((char)ch) { case 'a': aflag = 1; break; + case 'c': + cflag = 1; + break; case 'h': hflag = 1; break; @@ -137,19 +144,19 @@ warnx("command terminated abnormally"); exitonsig = WIFSIGNALED(status) ? WTERMSIG(status) : 0; showtime(out, &before_tv, &after, &ru); - if (lflag) { - int hz = getstathz(); - u_long ticks; - ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) + + /* get the number of ticks executed */ + hz = getstathz(); + ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) + hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000; + /* + * If our round-off on the tick calculation still puts us at 0, + * then always assume at least one tick. + */ + if (ticks == 0) + ticks = 1; - /* - * If our round-off on the tick calculation still puts us at 0, - * then always assume at least one tick. - */ - if (ticks == 0) - ticks = 1; + if (lflag) { fprintf(out, "%10ld %s\n", ru.ru_maxrss, "maximum resident set size"); @@ -179,6 +186,38 @@ ru.ru_nvcsw, "voluntary context switches"); fprintf(out, "%10ld %s\n", ru.ru_nivcsw, "involuntary context switches"); + } else if (cflag) { + int i; + /* + * csh prints: "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; + * result in: 0.000u 0.000s 0:05.01 0.0% 0+0k 0+0io 0pf+0w + */ + /* percent time spent running + * %P The CPU percentage computed as (%U + %S) / %E. + * do the math on ms. + */ + i = ((intmax_t)ru.ru_utime.tv_sec * 1000 + ru.ru_utime.tv_usec/1000 + + (intmax_t)ru.ru_stime.tv_sec * 1000 + ru.ru_stime.tv_usec/1000) + / ((intmax_t)after.tv_sec + after.tv_usec/(1000*1000)); + fprintf(out, "%d%c%1d%% ", i /10 , decimal_point, i % 10 ); + /* + * %X The average amount in (shared) text space used in Kbytes. + * %D The average amount in (unshared) data/stack space used in + * Kbytes. + */ + fprintf(out, "%ld+%ldk ", ru.ru_ixrss / ticks, (ru.ru_idrss + ru.ru_isrss) / ticks); + /* + * %I The number of input operations. + * %O The number of output operations. + */ + fprintf(out, "%ld+%ldio ", ru.ru_inblock, ru.ru_oublock); + /* + * %W Number of times the process was swapped. + * %F The number of major page faults (page needed to be brought + * from disk). + */ + fprintf(out, "%ldpf+%ldw", ru.ru_majflt, ru.ru_nswap); + fprintf(out, "\n"); } /* * If the child has exited on a signal, exit on the same @@ -202,7 +241,7 @@ usage(void) { fprintf(stderr, - "usage: time [-al] [-h | -p] [-o file] utility [argument ...]\n"); + "usage: time [-acl] [-h | -p] [-o file] utility [argument ...]\n"); exit(1); } @@ -276,6 +315,18 @@ fprintf(out, " user\t"); humantime(out, ru->ru_stime.tv_sec, ru->ru_stime.tv_usec/10000); fprintf(out, " sys\n"); + } else if (cflag) { + fprintf(out, "%jd%c%03ldu ", + (intmax_t)ru->ru_utime.tv_sec, decimal_point, + ru->ru_utime.tv_usec/1000); + fprintf(out, "%jd%c%03lds ", + (intmax_t)ru->ru_stime.tv_sec, decimal_point, + ru->ru_stime.tv_usec/1000); + /* realtime format is min:sec.dec */ + fprintf(out, "%jd%c%02ld%c%02ld ", + (intmax_t)after->tv_sec / 60, colon, + (intmax_t)after->tv_sec % 60, decimal_point, + after->tv_usec/1000); } else { fprintf(out, "%9jd%c%02ld real ", (intmax_t)after->tv_sec, decimal_point,