Handle SIGINFO in time(1) by printing the time the given command is running.
I find it quite handy to just hit ^T and see the time.
This commit is contained in:
parent
33cf0c5194
commit
b6d7073d13
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158560
@ -99,6 +99,15 @@ command which is similar or identical to this utility.
|
||||
Consult the
|
||||
.Xr builtin 1
|
||||
manual page.
|
||||
.Pp
|
||||
If
|
||||
.Nm
|
||||
receives a
|
||||
.Dv SIGINFO
|
||||
(see the status argument for
|
||||
.Xr stty 1 )
|
||||
signal, the current time the given command is running will be written to the
|
||||
standard output.
|
||||
.Sh ENVIRONMENT
|
||||
The
|
||||
.Ev PATH
|
||||
|
@ -63,19 +63,24 @@ static const char rcsid[] =
|
||||
|
||||
static int getstathz(void);
|
||||
static void humantime(FILE *, long, long);
|
||||
static void showtime(FILE *, struct timeval *, struct timeval *,
|
||||
struct rusage *);
|
||||
static void siginfo(int);
|
||||
static void usage(void);
|
||||
|
||||
static char decimal_point;
|
||||
static struct timeval before;
|
||||
static int hflag, pflag;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int aflag, ch, hflag, lflag, status, pflag;
|
||||
int aflag, ch, lflag, status;
|
||||
int exitonsig;
|
||||
pid_t pid;
|
||||
struct rlimit rl;
|
||||
struct rusage ru;
|
||||
struct timeval before, after;
|
||||
struct timeval after;
|
||||
char *ofn = NULL;
|
||||
FILE *out = stderr;
|
||||
|
||||
@ -130,46 +135,13 @@ main(int argc, char **argv)
|
||||
/* parent */
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
(void)signal(SIGINFO, siginfo);
|
||||
while (wait4(pid, &status, 0, &ru) != pid);
|
||||
gettimeofday(&after, (struct timezone *)NULL);
|
||||
if ( ! WIFEXITED(status))
|
||||
warnx("command terminated abnormally");
|
||||
exitonsig = WIFSIGNALED(status) ? WTERMSIG(status) : 0;
|
||||
after.tv_sec -= before.tv_sec;
|
||||
after.tv_usec -= before.tv_usec;
|
||||
if (after.tv_usec < 0)
|
||||
after.tv_sec--, after.tv_usec += 1000000;
|
||||
if (pflag) {
|
||||
/* POSIX wants output that must look like
|
||||
"real %f\nuser %f\nsys %f\n" and requires
|
||||
at least two digits after the radix. */
|
||||
fprintf(out, "real %ld%c%02ld\n",
|
||||
after.tv_sec, decimal_point,
|
||||
after.tv_usec/10000);
|
||||
fprintf(out, "user %ld%c%02ld\n",
|
||||
ru.ru_utime.tv_sec, decimal_point,
|
||||
ru.ru_utime.tv_usec/10000);
|
||||
fprintf(out, "sys %ld%c%02ld\n",
|
||||
ru.ru_stime.tv_sec, decimal_point,
|
||||
ru.ru_stime.tv_usec/10000);
|
||||
} else if (hflag) {
|
||||
humantime(out, after.tv_sec, after.tv_usec/10000);
|
||||
fprintf(out, " real\t");
|
||||
humantime(out, ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000);
|
||||
fprintf(out, " user\t");
|
||||
humantime(out, ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000);
|
||||
fprintf(out, " sys\n");
|
||||
} else {
|
||||
fprintf(out, "%9ld%c%02ld real ",
|
||||
after.tv_sec, decimal_point,
|
||||
after.tv_usec/10000);
|
||||
fprintf(out, "%9ld%c%02ld user ",
|
||||
ru.ru_utime.tv_sec, decimal_point,
|
||||
ru.ru_utime.tv_usec/10000);
|
||||
fprintf(out, "%9ld%c%02ld sys\n",
|
||||
ru.ru_stime.tv_sec, decimal_point,
|
||||
ru.ru_stime.tv_usec/10000);
|
||||
}
|
||||
showtime(out, &before, &after, &ru);
|
||||
if (lflag) {
|
||||
int hz = getstathz();
|
||||
u_long ticks;
|
||||
@ -278,3 +250,57 @@ humantime(FILE *out, long sec, long usec)
|
||||
fprintf(out, "%ldm", mins);
|
||||
fprintf(out, "%ld%c%02lds", sec, decimal_point, usec);
|
||||
}
|
||||
|
||||
static void
|
||||
showtime(FILE *out, struct timeval *before, struct timeval *after,
|
||||
struct rusage *ru)
|
||||
{
|
||||
|
||||
after->tv_sec -= before->tv_sec;
|
||||
after->tv_usec -= before->tv_usec;
|
||||
if (after->tv_usec < 0)
|
||||
after->tv_sec--, after->tv_usec += 1000000;
|
||||
|
||||
if (pflag) {
|
||||
/* POSIX wants output that must look like
|
||||
"real %f\nuser %f\nsys %f\n" and requires
|
||||
at least two digits after the radix. */
|
||||
fprintf(out, "real %ld%c%02ld\n",
|
||||
after->tv_sec, decimal_point,
|
||||
after->tv_usec/10000);
|
||||
fprintf(out, "user %ld%c%02ld\n",
|
||||
ru->ru_utime.tv_sec, decimal_point,
|
||||
ru->ru_utime.tv_usec/10000);
|
||||
fprintf(out, "sys %ld%c%02ld\n",
|
||||
ru->ru_stime.tv_sec, decimal_point,
|
||||
ru->ru_stime.tv_usec/10000);
|
||||
} else if (hflag) {
|
||||
humantime(out, after->tv_sec, after->tv_usec/10000);
|
||||
fprintf(out, " real\t");
|
||||
humantime(out, ru->ru_utime.tv_sec, ru->ru_utime.tv_usec/10000);
|
||||
fprintf(out, " user\t");
|
||||
humantime(out, ru->ru_stime.tv_sec, ru->ru_stime.tv_usec/10000);
|
||||
fprintf(out, " sys\n");
|
||||
} else {
|
||||
fprintf(out, "%9ld%c%02ld real ",
|
||||
after->tv_sec, decimal_point,
|
||||
after->tv_usec/10000);
|
||||
fprintf(out, "%9ld%c%02ld user ",
|
||||
ru->ru_utime.tv_sec, decimal_point,
|
||||
ru->ru_utime.tv_usec/10000);
|
||||
fprintf(out, "%9ld%c%02ld sys\n",
|
||||
ru->ru_stime.tv_sec, decimal_point,
|
||||
ru->ru_stime.tv_usec/10000);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
siginfo(int sig __unused)
|
||||
{
|
||||
struct timeval after;
|
||||
struct rusage ru;
|
||||
|
||||
gettimeofday(&after, (struct timezone *)NULL);
|
||||
getrusage(RUSAGE_CHILDREN, &ru);
|
||||
showtime(stdout, &before, &after, &ru);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user