commit 5c8d5c1dca2b973827cca99136a1f867971cc7f4
parent 7cc4ef0734f77c7b6cd35a6619bafafbe0e68de8
Author: Evan Gates <evan.gates@gmail.com>
Date: Fri, 27 Feb 2015 13:31:04 -0800
add time. do not mark complete/POSIX compliant as exit status is wrong.
Diffstat:
M | Makefile | | | 1 | + |
M | README | | | 1 | + |
A | time.c | | | 63 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -137,6 +137,7 @@ BIN =\
tar\
tee\
test\
+ time\
touch\
tr\
true\
diff --git a/README b/README
@@ -74,6 +74,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
=* tar non-posix none
=* tee yes none
=* test yes none
+= time no none (incorrect exit status)
=* touch yes none
#* tr yes none
=* true yes none
diff --git a/time.c b/time.c
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <sys/wait.h>
+
+#include "util.h"
+
+void
+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:");
+
+ if ((rbeg = times(&tms)) < 0) /* POSIX doesn't say NULL is ok... */
+ eprintf("times() failed to retrieve start times:");
+
+ if (!(pid = fork())) { /* child */
+ execvp(*argv, argv);
+ /* FIXME: check errno for POSIX exit status
+ * 126: found could not be invoked
+ * 127: could not be found
+ * problem is some like EACCESS can mean either...
+ * worth doing manual path search for correct value? also gives more
+ * accurate time as the patch search wouldn't be included in child's
+ * user/sys times... */
+ enprintf(127, "failed to exec %s:", *argv);
+ }
+ 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;
+}