Avoid use of printfs when emitting. DRY.
diff --git a/unix/Makefile b/unix/Makefile
index 920e767..801a801 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -2,12 +2,13 @@
ifeq ($(OS),Linux)
PRGLIBS=-lrt
SOLIBS=-ldl -lrt
-else
-LIBS=
+endif
+ifeq ($(OS),Darwin)
+PRGLIBS=
SOLIBS=
-endif
+endif
-CC=cc -D_GNU_SOURCE -D_BSD_SOURCE=1 -std=c99 -Wall -O3
+CC=cc -D_GNU_SOURCE -D_BSD_SOURCE=1 -std=c99 -Wall -O2 -fomit-frame-pointer -fno-stack-protector -Wno-incompatible-pointer-types
all: fsatrace fsatrace.so
diff --git a/unix/fsatrace.c b/unix/fsatrace.c
index 2ad695c..fe90f1d 100644
--- a/unix/fsatrace.c
+++ b/unix/fsatrace.c
@@ -6,6 +6,7 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <limits.h>
#include "fsatrace.h"
@@ -24,8 +25,8 @@
fd = 1;
if (fd < 0)
fprintf(stderr, "Unable to open output file '%s'\n", path);
- sz = *(size_t *) p;
- r = write(fd, p + sizeof(size_t), sz);
+ sz = (size_t) * (unsigned *)p;
+ r = write(fd, p + sizeof(unsigned), sz);
assert(r == sz);
if (fd != 1)
close(fd);
@@ -34,11 +35,21 @@
unsigned long
hash(unsigned char *str)
{
- unsigned long h = 5381;
- int c;
- while ((c = *str++))
- h = ((h << 5) + h) + c;
- return h;
+ unsigned long h = 5381;
+ int c;
+ while ((c = *str++))
+ h = ((h << 5) + h) + c;
+ return h;
+}
+
+static void
+fatal(const char *fmt,...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
}
int
@@ -52,10 +63,8 @@
int rc = EXIT_FAILURE;
int child;
const char *out;
- if (argc < 4 || strcmp(argv[2], "--")) {
- fprintf(stderr, "Usage: %s <output> -- <cmdline>\n", argv[0]);
- return rc;
- }
+ if (argc < 4 || strcmp(argv[2], "--"))
+ fatal("Usage: %s <output> -- <cmdline>\n", argv[0]);
out = argv[1];
snprintf(shname, sizeof(shname), "/%ld", hash((unsigned char *)out));
for (size_t i = 0, l = strlen(shname); i < l; i++)
@@ -66,23 +75,24 @@
r = ftruncate(fd, LOGSZ);
assert(!r);
buf = mmap(0, LOGSZ, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- snprintf(so, sizeof(so), "%s.so", argv[0]);
#ifdef __APPLE__
+ snprintf(so, sizeof(so), "%s.dylib", argv[0]);
setenv("DYLD_INSERT_LIBRARIES", so, 1);
setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1);
#else
+ snprintf(so, sizeof(so), "%s.so", argv[0]);
setenv("LD_PRELOAD", so, 1);
#endif
setenv(ENVOUT, shname, 1);
child = fork();
if (!child) {
execvp(argv[3], argv + 3);
- assert(0);
+ fatal("Unable to execute command '%s'\n", argv[3]);
}
r = wait(&rc);
assert(r >= 0);
rc = WEXITSTATUS(rc);
- if (!rc)
+ if (!rc || *out == '-')
dump(out, buf);
munmap(buf, LOGSZ);
close(fd);
diff --git a/unix/fsatraceso.c b/unix/fsatraceso.c
index 94cf27a..abb4edd 100644
--- a/unix/fsatraceso.c
+++ b/unix/fsatraceso.c
@@ -34,34 +34,6 @@
static char *s_buf;
static const int wmode = O_RDWR | O_WRONLY | O_APPEND | O_CREAT | O_TRUNC;
-static int
-good(const char *s, int sz)
-{
- int i;
- int bad = 0;
-
- for (i = 0; i < sz; i++)
- bad += s[i] == 0;
- return !bad;
-}
-
-static void
-swrite(const char *p, int sz)
-{
- int g;
- char *dst = s_buf + sizeof(size_t);
- size_t *psofar = (size_t *) s_buf;
- size_t sofar;
- if (!s_buf)
- return;
- sofar = __sync_fetch_and_add(psofar, sz);
- memcpy(dst + sofar, p, sz);
- g = good(p, sz);
- if (!g)
- fprintf(stderr, "BAD: %s\n", p);
- assert(g);
-}
-
static void
__attribute((constructor(101)))
init()
@@ -81,35 +53,63 @@
}
static inline void
+__attribute((noinline))
iemit(int c, const char *p1, const char *p2)
{
- char buf [10000];
- int sz = 0;
-
- sz += snprintf(buf, sizeof(buf) - 1 - sz, "%c|%s", c, p1);
- if (p2)
- sz += snprintf(buf + sz, sizeof(buf) - 1 - sz, "|%s", p2);
- sz += snprintf(buf + sz, sizeof(buf) - 1 - sz, "\n");
- assert(sz < sizeof(buf) - 1);
- buf[sz] = 0;
- swrite(buf, sz);
+ char *dst = s_buf + sizeof(unsigned);
+ unsigned *psofar = (unsigned *)s_buf;
+ unsigned sofar;
+ unsigned sz;
+ unsigned s1;
+ unsigned s2;
+ char *p;
+ if (!s_buf)
+ return;
+ s1 = strlen(p1);
+ sz = s1 + 3;
+ if (p2) {
+ s2 = strlen(p2);
+ sz += s2 + 1;
+ }
+ sofar = __sync_fetch_and_add(psofar, sz);
+ p = dst + sofar;
+ *p++ = c;
+ *p++ = '|';
+ memcpy(p, p1, s1);
+ p += s1;
+ if (p2) {
+ *p++ = '|';
+ memcpy(p, p2, s2);
+ p += s2;
+ }
+ *p++ = '\n';
}
static void
+__attribute((noinline))
emit(int c, const char *p1)
{
char ap [PATH_MAX];
iemit(c, realpath(p1, ap), 0);
}
+static void
+__attribute((noinline))
+resolv(void ** p, const char * n) {
+ if (!*p)
+ *p = dlsym(RTLD_NEXT, n);
+ assert(*p);
+}
+
+#define R(f) resolv((void**)&o##f, #f)
+
FILE *
fopen(const char *p, const char *m)
{
FILE *r;
static FILE *(*ofopen) (const char *, const char *)= 0;
- if (!ofopen)
- ofopen = dlsym(RTLD_NEXT, "fopen");
- assert(ofopen);
+ // resolv(&ofopen, "fopen");
+ R(fopen);
r = ofopen(p, m);
if (r)
emit(strchr(m, 'r') ? 'r' : 'w', p);
@@ -121,9 +121,7 @@
{
FILE *r;
static FILE *(*ofopen64) (const char *, const char *)= 0;
- if (!ofopen64)
- ofopen64 = dlsym(RTLD_NEXT, "fopen64");
- assert(ofopen64);
+ R(fopen64);
r = ofopen64(p, m);
if (r)
emit(strchr(m, 'r') ? 'r' : 'w', p);
@@ -135,9 +133,7 @@
{
int r;
static int (*oopen) (const char *, int, mode_t)= 0;
- if (!oopen)
- oopen = dlsym(RTLD_NEXT, "open");
- assert(oopen);
+ R(open);
r = oopen(p, f, m);
if (r >= 0)
emit(f & wmode ? 'w' : 'r', p);
@@ -149,9 +145,7 @@
{
int r;
static int (*oopen64) (const char *, int, mode_t)= 0;
- if (!oopen64)
- oopen64 = dlsym(RTLD_NEXT, "open64");
- assert(oopen64);
+ R(open64);
r = oopen64(p, f, m);
if (r >= 0)
emit(f & wmode ? 'w' : 'r', p);
@@ -164,14 +158,11 @@
int r;
if (fd != AT_FDCWD) {
static int (*oopenat) (int, const char *, int, mode_t)= 0;
- if (!oopenat)
- oopenat = dlsym(RTLD_NEXT, "openat");
- assert(oopenat);
+ R(openat);
r = oopenat(fd, p, f, m);
if (r >= 0)
iemit(f & wmode ? 'W' : 'R', p, 0);
- }
- else
+ } else
r = open(p, f, m);
return r;
}
@@ -182,14 +173,11 @@
int r;
if (fd != AT_FDCWD) {
static int (*oopenat64) (int, const char *, int, mode_t)= 0;
- if (!oopenat64)
- oopenat64 = dlsym(RTLD_NEXT, "openat64");
- assert(oopenat64);
+ R(openat64);
r = oopenat64(fd, p, f, m);
if (r >= 0)
iemit(f & wmode ? 'W' : 'R', p, 0);
- }
- else
+ } else
r = open64(p, f, m);
return r;
}
@@ -202,9 +190,7 @@
char b2 [PATH_MAX];
char *rp1 = realpath(p1, b1);
static int (*orename) (const char *, const char *)= 0;
- if (!orename)
- orename = dlsym(RTLD_NEXT, "rename");
- assert(orename);
+ R(rename);
r = orename(p1, p2);
if (!r)
iemit('m', realpath(p2, b2), rp1);
@@ -217,14 +203,11 @@
int r;
if (fd1 != AT_FDCWD || fd2 != AT_FDCWD) {
static int (*orenameat) (const char *, const char *)= 0;
- if (!orenameat)
- orenameat = dlsym(RTLD_NEXT, "renameat");
- assert(orenameat);
+ R(renameat);
r = orenameat(p1, p2);
if (!r)
iemit('R', p2, p1);
- }
- else
+ } else
r = rename(p1, p2);
return r;
}
@@ -236,9 +219,7 @@
char b [PATH_MAX];
char *rp = realpath(p, b);
static int (*ounlink) (const char *)= 0;
- if (!ounlink)
- ounlink = dlsym(RTLD_NEXT, "unlink");
- assert(ounlink);
+ R(unlink);
r = ounlink(p);
if (!r)
iemit('d', rp, 0);
@@ -251,15 +232,12 @@
int r;
if (fd != AT_FDCWD) {
static int (*ounlinkat) (int fd, const char *p, int f);
- if (!ounlinkat)
- ounlinkat = dlsym(RTLD_NEXT, "unlinkat");
- assert(ounlinkat);
+ R(unlinkat);
r = ounlinkat(fd, p, f);
if (!r)
iemit('D', p, 0);
assert(0);
- }
- else if (f & AT_REMOVEDIR)
+ } else if (f & AT_REMOVEDIR)
r = rmdir(p);
else
r = unlink(p);