commit a5bbdf7d866382d9fe868b59490e2847db94a939
Author: Evan Gates <[email protected]>
Date:   Fri Feb 27 13:31:04 2015 -0800

    add time. do not mark complete/POSIX compliant as exit status is wrong.

diff --git a/Makefile b/Makefile
index 527de2a..ef57715 100644
--- a/Makefile
+++ b/Makefile
@@ -137,6 +137,7 @@ BIN =\
        tar\
        tee\
        test\
+       time\
        touch\
        tr\
        true\
diff --git a/README b/README
index d98ecf5..17a5f87 100644
--- 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
new file mode 100644
index 0000000..71bf04d
--- /dev/null
+++ 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;
+}

Reply via email to