#if 0 /*─────────────────────────────────────────────────────────────────╗ │ To the extent possible under law, Justine Tunney has waived │ │ all copyright and related or neighboring rights to this file, │ │ as it is written in the following disclaimers: │ │ • http://unlicense.org/ │ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/struct/rusage.h" #include "libc/calls/calls.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/timespec.h" #include "libc/fmt/itoa.h" #include "libc/log/appendresourcereport.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/append.h" #include "libc/stdio/stdio.h" #include "libc/sysv/consts/sig.h" int main(int argc, char *argv[]) { const char *prog = argv[0]; if (!prog) prog = "rusage"; if (argc < 2) { tinyprint(2, prog, ": missing command\n", NULL); exit(1); } // block process management signals sigset_t mask, orig; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &orig); struct timespec started = timespec_real(); // launch subprocess int child = fork(); if (child == -1) { perror(prog); exit(1); } if (!child) { sigprocmask(SIG_SETMASK, &orig, 0); execvp(argv[1], argv + 1); _Exit(127); } // wait for subprocess int ws; struct rusage ru; struct sigaction ignore; ignore.sa_flags = 0; ignore.sa_handler = SIG_IGN; sigemptyset(&ignore.sa_mask); sigaction(SIGINT, &ignore, 0); sigaction(SIGQUIT, &ignore, 0); if (wait4(child, &ws, 0, &ru) == -1) { perror(prog); exit(1); } // compute wall time char strmicros[27]; struct timespec ended = timespec_real(); struct timespec elapsed = timespec_sub(ended, started); FormatInt64Thousands(strmicros, timespec_tomicros(elapsed)); // show report char *b = 0; appends(&b, "took "); appends(&b, strmicros); appends(&b, "µs wall time\n"); AppendResourceReport(&b, &ru, "\n"); write(2, b, appendz(b).i); // propagate status if (WIFSIGNALED(ws)) { signal(WTERMSIG(ws), SIG_DFL); raise(WTERMSIG(ws)); } return WEXITSTATUS(ws); }