diff --git a/aclocal.m4 b/aclocal.m4 index 515e35e..9f07f3d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -dnl $MirBSD: src/bin/ksh/aclocal.m4,v 2.4 2004/12/31 17:29:28 tg Exp $ +dnl $MirBSD: src/bin/ksh/aclocal.m4,v 2.5 2004/12/31 18:41:46 tg Exp $ dnl- dnl Copyright (c) 2004 dnl Thorsten "mirabile" Glaser @@ -281,45 +281,6 @@ AC_DEFUN(KSH_TIME_DECLARED, ])dnl dnl dnl -dnl Check for working times (ie, it exists and doesn't always return 0). -dnl Defines TIMES_BROKEN if it doesn't exist or if it always returns 0 -dnl (also checks for existance of getrusage if times doesn't work). -dnl XXX: requires clock_t to be typedefed/defined... -AC_DEFUN(KSH_TIMES_CHECK, - [AC_CACHE_CHECK(if times() is present/working, ksh_cv_func_times_ok, - [AC_TRY_RUN([ -#include -#include -/* if missing, clock_t is defined to be INT32 */ -#if SIZEOF_INT == 4 -# define INT32 int -#else /* SIZEOF_INT */ -# if SIZEOF_LONG == 4 -# define INT32 long -# else /* SIZEOF_LONG */ - #error cannot find 32 bit type... -# endif /* SIZEOF_LONG */ -#endif /* SIZEOF_INT */ - main() - { - extern clock_t times(); - struct tms tms; - times(&tms); - sleep(1); - if (times(&tms) == 0) - exit(1); - exit(0); - } - ], ksh_cv_func_times_ok=yes, ksh_cv_func_times_ok=no, - AC_MSG_ERROR(cannot determine if times works when cross compiling) - )]) - if test $ksh_cv_func_times_ok = no; then - AC_DEFINE(TIMES_BROKEN) - AC_CHECK_FUNCS(getrusage) - fi - ])dnl -dnl -dnl AC_DEFUN(KSH_C_VOID, [AC_CACHE_CHECK(if compiler understands void, ksh_cv_c_void, [AC_TRY_COMPILE( diff --git a/c_sh.c b/c_sh.c index a7f3078..37ef59a 100644 --- a/c_sh.c +++ b/c_sh.c @@ -1,19 +1,18 @@ -/** $MirBSD: src/bin/ksh/c_sh.c,v 2.10 2004/12/31 17:42:44 tg Exp $ */ -/* $OpenBSD: c_sh.c,v 1.21 2004/12/18 22:35:41 millert Exp $ */ +/** $MirBSD: src/bin/ksh/c_sh.c,v 2.11 2004/12/31 18:41:46 tg Exp $ */ +/* $OpenBSD: c_sh.c,v 1.25 2004/12/22 18:48:56 millert Exp $ */ /* * built-in Bourne commands */ #include "sh.h" -#include "ksh_stat.h" /* umask() */ -#include "ksh_time.h" -#include "ksh_times.h" +#include +#include +#include -__RCSID("$MirBSD: src/bin/ksh/c_sh.c,v 2.10 2004/12/31 17:42:44 tg Exp $"); - -static char *clocktos(clock_t t); +__RCSID("$MirBSD: src/bin/ksh/c_sh.c,v 2.11 2004/12/31 18:41:46 tg Exp $"); +static void p_time(struct shf *, int, struct timeval *, int, char *, char *); /* :, false and true */ int @@ -661,16 +660,31 @@ c_unset(char **wp) return ret; } +static void +p_time(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, (long)tv->tv_sec, tv->tv_usec / 10000, suffix); + else + shf_fprintf(shf, "%s%*ldm%ld.%02lds%s", prefix ? prefix : "", + width, (long)(tv->tv_sec / 60), (long)(tv->tv_sec % 60), + tv->tv_usec / 10000, suffix); +} + int c_times(char **wp GCC_FUNC_ATTR(unused)) { - struct tms all; + struct rusage usage; - (void) ksh_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_SELF, &usage); + p_time(shl_stdout, 0, &usage.ru_utime, 0, NULL, " "); + p_time(shl_stdout, 0, &usage.ru_stime, 0, NULL, "\n"); + + (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; } @@ -685,13 +699,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 = ksh_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 @@ -701,33 +717,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 = ksh_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; @@ -766,30 +794,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 GCC_FUNC_ATTR(unused)) diff --git a/config.h b/config.h index 3d0a6ba..8a34936 100644 --- a/config.h +++ b/config.h @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/config.h,v 2.4 2004/12/31 17:29:28 tg Exp $ */ +/** $MirBSD: src/bin/ksh/config.h,v 2.5 2004/12/31 18:41:46 tg Exp $ */ /* $OpenBSD: config.h,v 1.9 2003/10/22 07:40:38 jmc Exp $ */ /* @@ -142,9 +142,6 @@ /* Define if you have a sane header file */ /* #undef HAVE_TERMIO_H */ -/* Define if you don't have times() or if it always returns 0 */ -/* #undef TIMES_BROKEN */ - /* Define if opendir() will open non-directory files */ /* #undef OPENDIR_DOES_NONDIR */ diff --git a/configure.in b/configure.in index 4e35770..0a17b8b 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl $MirBSD: src/bin/ksh/configure.in,v 2.2 2004/12/28 22:44:39 tg Exp $ +dnl $MirBSD: src/bin/ksh/configure.in,v 2.3 2004/12/31 18:41:47 tg Exp $ dnl dnl Process this file with autoconf to produce a configure script dnl @@ -79,7 +79,6 @@ KSH_FUNC_LSTAT KSH_SYS_ERRLIST KSH_SYS_SIGLIST KSH_TIME_DECLARED -KSH_TIMES_CHECK dnl dnl Structures dnl diff --git a/jobs.c b/jobs.c index d7aee32..3ffe203 100644 --- a/jobs.c +++ b/jobs.c @@ -1,5 +1,5 @@ -/** $MirBSD: src/bin/ksh/jobs.c,v 2.7 2004/12/31 17:39:12 tg Exp $ */ -/* $OpenBSD: jobs.c,v 1.26 2004/12/18 22:12:23 millert Exp $ */ +/** $MirBSD: src/bin/ksh/jobs.c,v 2.8 2004/12/31 18:41:47 tg Exp $ */ +/* $OpenBSD: jobs.c,v 1.30 2004/12/22 18:48:56 millert Exp $ */ /* * Process and job control @@ -26,12 +26,13 @@ */ #include "sh.h" -#include "ksh_stat.h" +#include #include "ksh_wait.h" -#include "ksh_times.h" +#include +#include #include "tty.h" -__RCSID("$MirBSD: src/bin/ksh/jobs.c,v 2.7 2004/12/31 17:39:12 tg Exp $"); +__RCSID("$MirBSD: src/bin/ksh/jobs.c,v 2.8 2004/12/31 18:41:47 tg Exp $"); /* Start of system configuration stuff */ @@ -137,8 +138,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 */ @@ -167,7 +168,7 @@ static const char *const lookup_msgs[] = { "argument must be %job or process id", NULL }; -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; @@ -488,7 +489,8 @@ exchild(struct op *t, int flags, int close_fd) */ 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; @@ -1290,7 +1292,7 @@ j_sigchld(int sig GCC_FUNC_ATTR(unused)) Proc UNINITIALIZED(*p); int pid; WAIT_T status; - struct tms t0, t1; + struct rusage ru0, ru1; #ifdef JOB_SIGS /* Don't wait for any processes if a job is partially started. @@ -1305,7 +1307,7 @@ j_sigchld(int sig GCC_FUNC_ATTR(unused)) } #endif /* JOB_SIGS */ - ksh_times(&t0); + getrusage(RUSAGE_CHILDREN, &ru0); do { #ifdef JOB_SIGS pid = ksh_waitpid(-1, &status, (WNOHANG|WUNTRACED)); @@ -1316,7 +1318,7 @@ j_sigchld(int sig GCC_FUNC_ATTR(unused)) if (pid <= 0) /* return if would block (0) ... */ break; /* ... or no children or interrupted (-1) */ - ksh_times(&t1); + getrusage(RUSAGE_CHILDREN, &ru1); /* find job and process structures for this pid */ for (j = job_list; j != NULL; j = j->next) @@ -1329,13 +1331,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/ksh.1tbl b/ksh.1tbl index e7ccfd2..f83dc55 100644 --- a/ksh.1tbl +++ b/ksh.1tbl @@ -1,4 +1,4 @@ -.\" $MirBSD: src/bin/ksh/ksh.1tbl,v 2.8 2004/12/31 18:22:54 tg Exp $ +.\" $MirBSD: src/bin/ksh/ksh.1tbl,v 2.9 2004/12/31 18:41:47 tg Exp $ .\" $OpenBSD: ksh.1tbl,v 1.84 2004/12/22 18:58:44 millert Exp $ .\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $ .\" @@ -3864,21 +3864,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 +option is given the output is slightly longer: +.Bd -literal -offset indent +real 0.00 +user 0.00 +sys 0.00 +.Ed +.Pp +It is an error to specify the +.Fl p +option unless .Ar pipeline -is a simple command), in which case the output is slightly longer: +is a simple command. .Pp -.Dl real 0.00 -.Dl user 0.00 -.Dl sys 0.00 -.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 @@ -3889,8 +3892,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/ksh_times.h b/ksh_times.h deleted file mode 100644 index 2fc0f1a..0000000 --- a/ksh_times.h +++ /dev/null @@ -1,22 +0,0 @@ -/** $MirBSD: src/bin/ksh/ksh_times.h,v 2.1 2004/12/10 18:09:41 tg Exp $ */ -/* $OpenBSD: ksh_times.h,v 1.2 1996/10/01 02:05:41 downsj Exp $ */ - -#ifndef KSH_TIMES_H -#define KSH_TIMES_H - -/* Needed for clock_t on some systems (ie, NeXT in non-posix mode) */ -#include "ksh_time.h" - -#include - -#ifdef TIMES_BROKEN -extern clock_t ksh_times(struct tms *); -#else /* TIMES_BROKEN */ -# define ksh_times times -#endif /* TIMES_BROKEN */ - -#ifdef HAVE_TIMES -extern clock_t times(struct tms *); -#endif /* HAVE_TIMES */ - -#endif /* KSH_TIMES_H */ diff --git a/missing.c b/missing.c index 8bdd757..83df359 100644 --- a/missing.c +++ b/missing.c @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/missing.c,v 2.4 2004/12/18 19:22:30 tg Exp $ */ +/** $MirBSD: src/bin/ksh/missing.c,v 2.5 2004/12/31 18:41:47 tg Exp $ */ /* $OpenBSD: missing.c,v 1.5 2003/05/16 18:49:46 jsyn Exp $ */ /* @@ -9,7 +9,7 @@ #include "ksh_stat.h" #include "ksh_dir.h" -__RCSID("$MirBSD: src/bin/ksh/missing.c,v 2.4 2004/12/18 19:22:30 tg Exp $"); +__RCSID("$MirBSD: src/bin/ksh/missing.c,v 2.5 2004/12/31 18:41:47 tg Exp $"); #ifndef HAVE_MEMSET void * @@ -189,65 +189,6 @@ strerror(err) } #endif /* !HAVE_STRERROR */ -#ifdef TIMES_BROKEN -# include "ksh_time.h" -# include "ksh_times.h" -# ifdef HAVE_GETRUSAGE -# include -# else /* HAVE_GETRUSAGE */ -# include -# endif /* HAVE_GETRUSAGE */ - -clock_t -ksh_times(tms) - struct tms *tms; -{ - static clock_t base_sec; - clock_t rv; - -# ifdef HAVE_GETRUSAGE - { - struct timeval tv; - struct rusage ru; - - getrusage(RUSAGE_SELF, &ru); - tms->tms_utime = ru.ru_utime.tv_sec * CLK_TCK - + ru.ru_utime.tv_usec * CLK_TCK / 1000000; - tms->tms_stime = ru.ru_stime.tv_sec * CLK_TCK - + ru.ru_stime.tv_usec * CLK_TCK / 1000000; - - getrusage(RUSAGE_CHILDREN, &ru); - tms->tms_cutime = ru.ru_utime.tv_sec * CLK_TCK - + ru.ru_utime.tv_usec * CLK_TCK / 1000000; - tms->tms_cstime = ru.ru_stime.tv_sec * CLK_TCK - + ru.ru_stime.tv_usec * CLK_TCK / 1000000; - - gettimeofday(&tv, NULL); - if (base_sec == 0) - base_sec = tv.tv_sec; - rv = (tv.tv_sec - base_sec) * CLK_TCK; - rv += tv.tv_usec * CLK_TCK / 1000000; - } -# else /* HAVE_GETRUSAGE */ - /* Assume times() available, but always returns 0 - * (also assumes ftime() available) - */ - { - struct timeb tb; - - if (times(tms) == (clock_t) -1) - return (clock_t) -1; - ftime(&tb); - if (base_sec == 0) - base_sec = tb.time; - rv = (tb.time - base_sec) * CLK_TCK; - rv += tb.millitm * CLK_TCK / 1000; - } -# endif /* HAVE_GETRUSAGE */ - return rv; -} -#endif /* TIMES_BROKEN */ - #ifdef OPENDIR_DOES_NONDIR /* Prevent opendir() from attempting to open non-directories. Such * behavior can cause problems if it attempts to open special devices...