summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-12-22 18:48:57 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-12-22 18:48:57 +0000
commitd26ff498a561775b6ff5b455c61f11e4cd8bd873 (patch)
treeff4e518d3293d20627c5c54ae78236d553c9f434 /bin/ksh
parent789ed5943cc6349ea0276feedb68a6131a42455d (diff)
Our times(3) just calls getrusage(2) and gettimeofday(2), converting seconds
to ticks. Since ksh needs things in seconds it then converted them back. Avoid the silliness and use the getrusage(2) and gettimeofday(2) directly. With man page help from jmc@
Diffstat (limited to 'bin/ksh')
-rw-r--r--bin/ksh/c_sh.c116
-rw-r--r--bin/ksh/jobs.c30
-rw-r--r--bin/ksh/ksh.136
-rw-r--r--bin/ksh/ksh.1tbl36
-rw-r--r--bin/ksh/sh.111
-rw-r--r--bin/ksh/sh.1tbl11
6 files changed, 140 insertions, 100 deletions
diff --git a/bin/ksh/c_sh.c b/bin/ksh/c_sh.c
index f31c2c0a013..ef25f3d9a1b 100644
--- a/bin/ksh/c_sh.c
+++ b/bin/ksh/c_sh.c
@@ -1,15 +1,15 @@
-/* $OpenBSD: c_sh.c,v 1.24 2004/12/22 17:14:34 millert Exp $ */
+/* $OpenBSD: c_sh.c,v 1.25 2004/12/22 18:48:56 millert Exp $ */
/*
* built-in Bourne commands
*/
#include "sh.h"
-#include <sys/stat.h> /* umask() */
-#include <sys/times.h>
-
-static char *clocktos(clock_t);
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+static void p_time(struct shf *, int, struct timeval *, int, char *, char *);
/* :, false and true */
int
@@ -669,16 +669,36 @@ c_unset(char **wp)
return ret;
}
+static void
+p_time(shf, posix, tv, width, prefix, suffix)
+ struct shf *shf;
+ int posix;
+ struct timeval *tv;
+ int width;
+ char *prefix;
+ char *suffix;
+{
+ if (posix)
+ shf_fprintf(shf, "%s%*ld.%02ld%s", prefix ? prefix : "",
+ width, tv->tv_sec, tv->tv_usec / 10000, suffix);
+ else
+ shf_fprintf(shf, "%s%*ldm%ld.%02lds%s", prefix ? prefix : "",
+ width, tv->tv_sec / 60, tv->tv_sec % 60,
+ tv->tv_usec / 10000, suffix);
+}
+
int
c_times(char **wp)
{
- struct tms all;
+ struct rusage usage;
+
+ (void) getrusage(RUSAGE_SELF, &usage);
+ p_time(shl_stdout, 0, &usage.ru_utime, 0, NULL, " ");
+ p_time(shl_stdout, 0, &usage.ru_stime, 0, NULL, "\n");
- (void) times(&all);
- shprintf("Shell: %8ss user ", clocktos(all.tms_utime));
- shprintf("%8ss system\n", clocktos(all.tms_stime));
- shprintf("Kids: %8ss user ", clocktos(all.tms_cutime));
- shprintf("%8ss system\n", clocktos(all.tms_cstime));
+ (void) getrusage(RUSAGE_CHILDREN, &usage);
+ p_time(shl_stdout, 0, &usage.ru_utime, 0, NULL, " ");
+ p_time(shl_stdout, 0, &usage.ru_stime, 0, NULL, "\n");
return 0;
}
@@ -693,13 +713,15 @@ timex(struct op *t, int f)
#define TF_NOREAL BIT(1) /* don't report real time */
#define TF_POSIX BIT(2) /* report in posix format */
int rv = 0;
- struct tms t0, t1, tms;
- clock_t t0t, t1t = 0;
+ struct rusage ru0, ru1, cru0, cru1;
+ struct timeval usrtime, systime, tv0, tv1;
int tf = 0;
- extern clock_t j_usrtime, j_systime; /* computed by j_wait */
+ extern struct timeval j_usrtime, j_systime; /* computed by j_wait */
char opts[1];
- t0t = times(&t0);
+ gettimeofday(&tv0, NULL);
+ getrusage(RUSAGE_SELF, &ru0);
+ getrusage(RUSAGE_CHILDREN, &cru0);
if (t->left) {
/*
* Two ways of getting cpu usage of a command: just use t0
@@ -709,33 +731,45 @@ timex(struct op *t, int f)
* pdksh tries to do the later (the j_usrtime hack doesn't
* really work as it only counts the last job).
*/
- j_usrtime = j_systime = 0;
+ timerclear(&j_usrtime);
+ timerclear(&j_systime);
if (t->left->type == TCOM)
t->left->str = opts;
opts[0] = 0;
rv = execute(t->left, f | XTIME);
tf |= opts[0];
- t1t = times(&t1);
+ gettimeofday(&tv1, NULL);
+ getrusage(RUSAGE_SELF, &ru1);
+ getrusage(RUSAGE_CHILDREN, &cru1);
} else
tf = TF_NOARGS;
if (tf & TF_NOARGS) { /* ksh93 - report shell times (shell+kids) */
tf |= TF_NOREAL;
- tms.tms_utime = t0.tms_utime + t0.tms_cutime;
- tms.tms_stime = t0.tms_stime + t0.tms_cstime;
+ timeradd(&ru0.ru_utime, &cru0.ru_utime, &usrtime);
+ timeradd(&ru0.ru_stime, &cru0.ru_stime, &systime);
} else {
- tms.tms_utime = t1.tms_utime - t0.tms_utime + j_usrtime;
- tms.tms_stime = t1.tms_stime - t0.tms_stime + j_systime;
+ timersub(&ru1.ru_utime, &ru0.ru_utime, &usrtime);
+ timeradd(&usrtime, &j_usrtime, &usrtime);
+ timersub(&ru1.ru_stime, &ru0.ru_stime, &systime);
+ timeradd(&systime, &j_systime, &systime);
}
- if (!(tf & TF_NOREAL))
- shf_fprintf(shl_out,
- tf & TF_POSIX ? "real %8s\n" : "%8ss real ",
- clocktos(t1t - t0t));
- shf_fprintf(shl_out, tf & TF_POSIX ? "user %8s\n" : "%8ss user ",
- clocktos(tms.tms_utime));
- shf_fprintf(shl_out, tf & TF_POSIX ? "sys %8s\n" : "%8ss system\n",
- clocktos(tms.tms_stime));
+ if (!(tf & TF_NOREAL)) {
+ timersub(&tv1, &tv0, &tv1);
+ if (tf & TF_POSIX)
+ p_time(shl_out, 1, &tv1, 5, "real ", "\n");
+ else
+ p_time(shl_out, 0, &tv1, 5, NULL, " real ");
+ }
+ if (tf & TF_POSIX)
+ p_time(shl_out, 1, &usrtime, 5, "user ", "\n");
+ else
+ p_time(shl_out, 0, &usrtime, 5, NULL, " user ");
+ if (tf & TF_POSIX)
+ p_time(shl_out, 1, &systime, 5, "sys ", "\n");
+ else
+ p_time(shl_out, 0, &systime, 5, NULL, " system\n");
shf_flush(shl_out);
return rv;
@@ -774,30 +808,6 @@ timex_hook(struct op *t, char **volatile *app)
*app = wp;
}
-static char *
-clocktos(clock_t t)
-{
- static char temp[22]; /* enough for 64 bit clock_t */
- int i;
- char *cp = temp + sizeof(temp);
-
- /* note: posix says must use max precision, ie, if clk_tck is
- * 1000, must print 3 places after decimal (if non-zero, else 1).
- */
- if (CLK_TCK != 100) /* convert to 1/100'ths */
- t = (t < 1000000000/CLK_TCK) ?
- (t * 100) / CLK_TCK : (t / CLK_TCK) * 100;
-
- *--cp = '\0';
- for (i = -2; i <= 0 || t > 0; i++) {
- if (i == 0)
- *--cp = '.';
- *--cp = '0' + (char)(t%10);
- t /= 10;
- }
- return cp;
-}
-
/* exec with no args - args case is taken care of in comexec() */
int
c_exec(char **wp)
diff --git a/bin/ksh/jobs.c b/bin/ksh/jobs.c
index ecd04520a06..65851bf1845 100644
--- a/bin/ksh/jobs.c
+++ b/bin/ksh/jobs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: jobs.c,v 1.29 2004/12/22 17:14:34 millert Exp $ */
+/* $OpenBSD: jobs.c,v 1.30 2004/12/22 18:48:56 millert Exp $ */
/*
* Process and job control
@@ -18,7 +18,8 @@
#include "sh.h"
#include <sys/stat.h>
#include <sys/wait.h>
-#include <sys/times.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include "tty.h"
/* Order important! */
@@ -71,8 +72,8 @@ struct job {
pid_t pgrp; /* process group of job */
pid_t ppid; /* pid of process that forked job */
INT32 age; /* number of jobs started */
- clock_t systime; /* system time used by job */
- clock_t usrtime; /* user time used by job */
+ struct timeval systime; /* system time used by job */
+ struct timeval usrtime; /* user time used by job */
Proc *proc_list; /* process list */
Proc *last_proc; /* last process in list */
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
@@ -101,7 +102,7 @@ static const char *const lookup_msgs[] = {
"argument must be %job or process id",
(char *) 0
};
-clock_t j_systime, j_usrtime; /* user and system time of last j_waitjed job */
+struct timeval j_systime, j_usrtime; /* user and system time of last j_waitjed job */
static Job *job_list; /* job list */
static Job *last_job;
@@ -364,7 +365,8 @@ exchild(struct op *t, int flags,
*/
j->flags = (flags & XXCOM) ? JF_XXCOM
: ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
- j->usrtime = j->systime = 0;
+ timerclear(&j->usrtime);
+ timerclear(&j->systime);
j->state = PRUNNING;
j->pgrp = 0;
j->ppid = procpid;
@@ -1080,7 +1082,7 @@ j_sigchld(int sig)
Proc *p = NULL;
int pid;
int status;
- struct tms t0, t1;
+ struct rusage ru0, ru1;
/* Don't wait for any processes if a job is partially started.
* This is so we don't do away with the process group leader
@@ -1093,14 +1095,14 @@ j_sigchld(int sig)
return;
}
- times(&t0);
+ getrusage(RUSAGE_CHILDREN, &ru0);
do {
pid = waitpid(-1, &status, (WNOHANG|WUNTRACED));
if (pid <= 0) /* return if would block (0) ... */
break; /* ... or no children or interrupted (-1) */
- times(&t1);
+ getrusage(RUSAGE_CHILDREN, &ru1);
/* find job and process structures for this pid */
for (j = job_list; j != (Job *) 0; j = j->next)
@@ -1113,13 +1115,15 @@ found:
warningf(true, "bad process waited for (pid = %d)",
pid);
*/
- t0 = t1;
+ ru0 = ru1;
continue;
}
- j->usrtime += t1.tms_cutime - t0.tms_cutime;
- j->systime += t1.tms_cstime - t0.tms_cstime;
- t0 = t1;
+ timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime);
+ timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime);
+ timeradd(&j->systime, &ru1.ru_stime, &j->systime);
+ timersub(&j->systime, &ru0.ru_stime, &j->systime);
+ ru0 = ru1;
p->status = status;
#ifdef JOBS
if (WIFSTOPPED(status))
diff --git a/bin/ksh/ksh.1 b/bin/ksh/ksh.1
index 74391cdc99d..0c9330b1599 100644
--- a/bin/ksh/ksh.1
+++ b/bin/ksh/ksh.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ksh.1,v 1.82 2004/12/16 02:10:59 jaredy Exp $
+.\" $OpenBSD: ksh.1,v 1.83 2004/12/22 18:48:56 millert Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -3980,21 +3980,24 @@ the user CPU time (time spent running in user mode), and the system CPU time
(time spent running in kernel mode).
Times are reported to standard error; the format of the output is:
.Pp
-.Dl 0.00s real 0.00s user 0.00s system
+.Dl "0m0.00s real 0m0.00s user 0m0.00s system"
.Pp
-unless the
+If the
.Fl p
-option is given (only possible if
-.Ar pipeline
-is a simple command), in which case the output is slightly longer:
+option is given the output is slightly longer:
+.Bd -literal -offset indent
+real 0.00
+user 0.00
+sys 0.00
+.Ed
.Pp
-.Dl real 0.00
-.Dl user 0.00
-.Dl sys 0.00
+It is an error to specify the
+.Fl p
+option unless
+.Ar pipeline
+is a simple command.
.Pp
-(the number of digits after the decimal may vary from system to system).
-Note
-that simple redirections of standard error do not effect the output of the
+Simple redirections of standard error do not effect the output of the
.Ic time
command:
.Pp
@@ -4005,8 +4008,13 @@ Times for the first command do not go to
.Dq afile ,
but those of the second command do.
.It Ic times
-Print the accumulated user and system times used by the shell and by processes
-which have exited that the shell started.
+Print the accumulated user and system times used both by the shell
+and by processes that the shell started which have exited.
+The format of the output is:
+.Bd -literal -offset indent
+0m0.00s 0m0.00s
+0m0.00s 0m0.00s
+.Ed
.It Ic trap Op Ar handler signal ...
Sets a trap handler that is to be executed when any of the specified signals are
received.
diff --git a/bin/ksh/ksh.1tbl b/bin/ksh/ksh.1tbl
index eb6c0548444..db6d1a57454 100644
--- a/bin/ksh/ksh.1tbl
+++ b/bin/ksh/ksh.1tbl
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ksh.1tbl,v 1.82 2004/12/16 02:10:59 jaredy Exp $
+.\" $OpenBSD: ksh.1tbl,v 1.83 2004/12/22 18:48:56 millert Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -3980,21 +3980,24 @@ the user CPU time (time spent running in user mode), and the system CPU time
(time spent running in kernel mode).
Times are reported to standard error; the format of the output is:
.Pp
-.Dl 0.00s real 0.00s user 0.00s system
+.Dl "0m0.00s real 0m0.00s user 0m0.00s system"
.Pp
-unless the
+If the
.Fl p
-option is given (only possible if
-.Ar pipeline
-is a simple command), in which case the output is slightly longer:
+option is given the output is slightly longer:
+.Bd -literal -offset indent
+real 0.00
+user 0.00
+sys 0.00
+.Ed
.Pp
-.Dl real 0.00
-.Dl user 0.00
-.Dl sys 0.00
+It is an error to specify the
+.Fl p
+option unless
+.Ar pipeline
+is a simple command.
.Pp
-(the number of digits after the decimal may vary from system to system).
-Note
-that simple redirections of standard error do not effect the output of the
+Simple redirections of standard error do not effect the output of the
.Ic time
command:
.Pp
@@ -4005,8 +4008,13 @@ Times for the first command do not go to
.Dq afile ,
but those of the second command do.
.It Ic times
-Print the accumulated user and system times used by the shell and by processes
-which have exited that the shell started.
+Print the accumulated user and system times used both by the shell
+and by processes that the shell started which have exited.
+The format of the output is:
+.Bd -literal -offset indent
+0m0.00s 0m0.00s
+0m0.00s 0m0.00s
+.Ed
.It Ic trap Op Ar handler signal ...
Sets a trap handler that is to be executed when any of the specified signals are
received.
diff --git a/bin/ksh/sh.1 b/bin/ksh/sh.1
index fb43b599d24..fce1d6b72d8 100644
--- a/bin/ksh/sh.1
+++ b/bin/ksh/sh.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sh.1,v 1.55 2004/12/12 17:37:45 jmc Exp $
+.\" $OpenBSD: sh.1,v 1.56 2004/12/22 18:48:56 millert Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -3256,8 +3256,13 @@ Use tests like
.Ic if \&[ \&"X$foo\&" = Xbar \&]
instead.
.It Ic times
-Print the accumulated user and system times used by the shell and by processes
-which have exited that the shell started.
+Print the accumulated user and system times used both by the shell
+and by processes that the shell started which have exited.
+The format of the output is:
+.Bd -literal -offset indent
+0m0.00s 0m0.00s
+0m0.00s 0m0.00s
+.Ed
.It Ic trap Op Ar handler signal ...
Sets a trap handler that is to be executed when any of the specified signals are
received.
diff --git a/bin/ksh/sh.1tbl b/bin/ksh/sh.1tbl
index ccf5c262efc..cdcd8b5d41a 100644
--- a/bin/ksh/sh.1tbl
+++ b/bin/ksh/sh.1tbl
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sh.1tbl,v 1.55 2004/12/12 17:37:45 jmc Exp $
+.\" $OpenBSD: sh.1tbl,v 1.56 2004/12/22 18:48:56 millert Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -3256,8 +3256,13 @@ Use tests like
.Ic if \&[ \&"X$foo\&" = Xbar \&]
instead.
.It Ic times
-Print the accumulated user and system times used by the shell and by processes
-which have exited that the shell started.
+Print the accumulated user and system times used both by the shell
+and by processes that the shell started which have exited.
+The format of the output is:
+.Bd -literal -offset indent
+0m0.00s 0m0.00s
+0m0.00s 0m0.00s
+.Ed
.It Ic trap Op Ar handler signal ...
Sets a trap handler that is to be executed when any of the specified signals are
received.