strscan: make it work properly
[tools.git] / tools / rusage_precise.c
1 #include <stdio.h>
2 #include <sys/time.h>
3 #include <sys/resource.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <errno.h>
9
10 #define eprintf(...) fprintf(stderr, __VA_ARGS__) 
11 #define FARG_TIMEVAL(tv) tv.tv_sec, tv.tv_usec
12 #define FSTR_TIMEVAL "%li.%06li"
13
14 int main(int argc, char **argv) {
15   #define CHECK_USAGE if (argc < 2) return eprintf("invocation: rusage_precise [--machine-readable] <command> [<args...>]\n"), 1;
16   CHECK_USAGE
17   int machine_readable = 0;
18   if (!strcmp(argv[1], "--machine-readable")) machine_readable = 1, argv++, argc--;
19   CHECK_USAGE
20
21   pid_t child = fork();
22   if (child == -1) return perror("fork failed"), 1;
23   if (child == 0) {
24     execvp(argv[1], argv+1);
25     return perror("execvp failed"), 1;
26   }
27
28   int status;
29   struct rusage ru;
30   errno = 0;
31   if (wait4(child, &status, 0, &ru) != child) return perror("wait4 failed"), 1;
32
33   if (machine_readable) {
34     eprintf(FSTR_TIMEVAL "\t" FSTR_TIMEVAL "\t%li\t%li\t%li\t%li\t%li\t%li\t%li\n",
35             FARG_TIMEVAL(ru.ru_utime), FARG_TIMEVAL(ru.ru_stime),
36             ru.ru_maxrss, ru.ru_minflt, ru.ru_majflt,
37             ru.ru_inblock, ru.ru_oublock, ru.ru_nvcsw,
38             ru.ru_nivcsw);
39   } else {
40     eprintf("        user CPU (s): " FSTR_TIMEVAL "\n", FARG_TIMEVAL(ru.ru_utime));
41     eprintf("      system CPU (s): " FSTR_TIMEVAL "\n", FARG_TIMEVAL(ru.ru_stime));
42     eprintf("   max RSS size (kB): %li\n", ru.ru_maxrss);
43     eprintf("        minor faults: %li\n", ru.ru_minflt);
44     eprintf("        major faults: %li\n", ru.ru_majflt);
45     eprintf("         fs inblocks: %li\n", ru.ru_inblock);
46     eprintf("        fs outblocks: %li\n", ru.ru_oublock);
47     eprintf("  voluntary switches: %li\n", ru.ru_nvcsw);
48     eprintf("involuntary switches: %li\n", ru.ru_nivcsw);
49   }
50   return 0;
51 }