blob: 46a74a75df6f43a3edafa28a3bf8a32eeb729eff [file]
#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'];
enum procerr ret = procRun(nargs, args, &rc, out);
switch (ret) {
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, "unknown process error");
break;
case ERR_PROC_WAIT:
if (verr)
aerror(nargs, args, "waiting for command completion");
break;
case ERR_FIFO_TIMEOUT:
aerror(nargs, args,
"Timeout opening the FIFO for writing the traced operations.\n"
"\n"
"This is more than likely because the process being traced does\n"
"not dynamically link libc. The fsatrace program uses LD_PRELOAD\n"
"to inject hooks around libc calls, and this error should only\n"
"occur when those hooks are not injected into the process being\n"
"traced.\n"
"\n"
"A simple \"fix\" is to wrap the program being launched inside\n"
"another program that dynmically links libc, but that approach\n"
"is invalid because the process not dynamically linking libc\n"
"indicates the process will not run the hooks installed by\n"
"fsatrace to trace filesystem accesses. Thus, doing something\n"
"like `bash -c \"exec my_program\"` is unlikely to achieve your\n"
"reason for using fsatrace in the first place.\n"
"\n"
);
break;
case ERR_FIFO_UNKNOWN:
aerror(nargs, args, "Error opening FIFO for writing the traced operations.");
break;
case OK:
if (rc) {
if (verr)
aerror(nargs, args,
"command failed with code %d", rc);
}
break;
default:
aerror(nargs, args, "Uncaught procerr %d", ret);
}
return rc;
}