2015-02-27 21:43:11 +00:00
|
|
|
/* See LICENSE file for copyright and license details. */
|
2015-02-27 21:31:04 +00:00
|
|
|
#include <sys/times.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
2015-02-27 21:43:11 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2015-02-27 21:31:04 +00:00
|
|
|
#include "util.h"
|
|
|
|
|
2015-02-27 21:43:11 +00:00
|
|
|
static void
|
2015-02-27 21:31:04 +00:00
|
|
|
usage(void)
|
|
|
|
{
|
|
|
|
eprintf("usage: %s [-p] utility [argument ...]\n", argv0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
pid_t pid;
|
|
|
|
struct tms tms; /* hold user and sys times */
|
|
|
|
clock_t rbeg, rend; /* real time */
|
|
|
|
long ticks; /* per second */
|
|
|
|
int status;
|
|
|
|
|
|
|
|
ARGBEGIN {
|
|
|
|
case 'p':
|
|
|
|
/* used to specify POSIX output format, but that's the only format we
|
|
|
|
* have for now */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
} ARGEND;
|
|
|
|
|
|
|
|
if (!*argv)
|
|
|
|
usage();
|
|
|
|
|
|
|
|
if ((ticks = sysconf(_SC_CLK_TCK)) < 0)
|
|
|
|
eprintf("sysconf() failed to retrieve clock ticks per second:");
|
|
|
|
|
2015-02-27 21:43:11 +00:00
|
|
|
if ((rbeg = times(&tms)) < 0)
|
2015-02-27 21:31:04 +00:00
|
|
|
eprintf("times() failed to retrieve start times:");
|
|
|
|
|
|
|
|
if (!(pid = fork())) { /* child */
|
|
|
|
execvp(*argv, argv);
|
2015-02-27 21:43:11 +00:00
|
|
|
enprintf(errno == ENOENT ? 127 : 126, "failed to exec %s:", *argv);
|
2015-02-27 21:31:04 +00:00
|
|
|
}
|
|
|
|
waitpid(pid, &status, 0);
|
|
|
|
|
|
|
|
if ((rend = times(&tms)) < 0)
|
|
|
|
eprintf("times() failed to retrieve end times:");
|
|
|
|
|
|
|
|
fprintf(stderr, "real %f\nuser %f\nsys %f\n",
|
|
|
|
(rend - rbeg) / (double)ticks,
|
|
|
|
tms.tms_cutime / (double)ticks,
|
|
|
|
tms.tms_cstime / (double)ticks);
|
|
|
|
|
|
|
|
return WIFEXITED(status) ? WEXITSTATUS(status) : 0;
|
|
|
|
}
|