| #include <sys/types.h> |
| #include <inttypes.h> |
| #include <assert.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <fcntl.h> |
| #include <limits.h> |
| #ifdef _MSC_VER |
| #include <io.h> |
| #define ssize_t size_t |
| #define basename(x) strrchr(x, '\\') + 1 |
| #else |
| #include <unistd.h> |
| #include <libgen.h> |
| #endif |
| |
| #include "fsatrace.h" |
| #include "proc.h" |
| |
| int |
| main(int argc, char *const argv[]) |
| { |
| int rc = EXIT_FAILURE; |
| const char *out; |
| const char *opts; |
| char bopts[256]; |
| int verr; |
| char *const *args = argv + 4; |
| unsigned nargs = argc - 4; |
| |
| if (argc < 5 || (strcmp(argv[3], "--") && strcmp(argv[3], "---"))) |
| fatal( |
| " usage: %s <options> <output> -- <cmdline>\n" |
| " where <options> is a combination of the following characters:\n" |
| " v: print args vector\n" |
| " e: print verbose errors\n" |
| " r: dump read operations\n" |
| " w: dump write operations\n" |
| " m: dump file move operations\n" |
| " d: dump file delete operations\n" |
| " q: dump file stat operations\n", |
| argv[0]); |
| out = argv[2]; |
| fflush(stdout); |
| opts = (const char *)argv[1]; |
| setenv(ENV_OPTS, opts, 1); |
| memset(bopts, 0, sizeof(bopts)); |
| while (*opts) |
| bopts[(unsigned char)*opts++] = 1; |
| if (bopts['v']) |
| procDumpArgs(nargs, args); |
| verr = bopts['e']; |
| switch (procRun(nargs, args, &rc, out)) { |
| case ERR_PROC_FORK: |
| if (verr) |
| aerror(nargs, args, "forking process"); |
| break; |
| case ERR_PROC_EXEC: |
| if (verr) |
| aerror(nargs, args, "executing command: %d", rc); |
| break; |
| case ERR_PROC_SIGNALED: |
| if (verr) |
| aerror(nargs, args, "process signaled: %d", rc); |
| break; |
| case ERR_PROC_STOPPED: |
| if (verr) |
| aerror(nargs, args, "process stopped: %d", rc); |
| break; |
| case ERR_PROC_UNKNOWN: |
| if (verr) |
| aerror(nargs, args, "unknow process error"); |
| break; |
| case ERR_PROC_WAIT: |
| if (verr) |
| aerror(nargs, args, "waiting for command completion"); |
| break; |
| default: |
| if (rc) { |
| if (verr) |
| aerror(nargs, args, |
| "command failed with code %d", rc); |
| } |
| } |
| return rc; |
| } |