#include #include #include #include #define _FCNTL_H #include #include #include #include static int (*oldopen)(const char *, int, mode_t); static ssize_t (*oldwrite)(int, const void *, size_t); static int (*oldclose)(int); static void * libc; static time_t ltime = -1; static int ifdlist[32] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int ofdlist[32] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static time_t times[32]; static int seq; #define xabort() do { fprintf(stderr, "aborting: %d\n", __LINE__); abort(); } while (0) static int olookup(int ifd) { int i; int ret = -1; for (i = 0; i < sizeof(ifdlist)/sizeof(ifdlist[0]); i++) { if (ifdlist[i] == ifd) { ret = i; break; } } return ret; } static void dlcheck(void) { if (!libc) { libc = dlopen("/lib/libc.so.6", RTLD_NOW); if (!libc) xabort(); oldopen = dlsym(libc, "open"); oldwrite = dlsym(libc, "write"); oldclose = dlsym(libc, "close"); if (!oldopen || !oldwrite || !oldclose) xabort(); ltime = time(NULL); } } static int openfile(void) { char out[64]; snprintf(out, 64, "/tmp/dsp-%ld-%d", ltime, seq); seq++; /* racy */ return oldopen(out, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU); } static void add(int fd) { int i; int j = -1; int ofd; // xabort(); for (i = 0; i < sizeof(ifdlist)/sizeof(ifdlist[0]); i++) { if (j == -1 && ifdlist[i] == -1) { j = i; } if (ifdlist[i] == fd) { xabort(); } } if (j == -1) return; ofd = openfile(); if (ofd == -1) return; ifdlist[j] = fd; if (ofdlist[j] != -1) xabort(); ofdlist[j] = ofd; } /* i != -1 */ static void ofdclose(int i) { oldclose(ofdlist[i]); ofdlist[i] = -1; ifdlist[i] = -1; times[i] = 0; } int open(const char *fn, int flags, mode_t mode) { int ret; dlcheck(); ret = oldopen(fn, flags, mode); if (!strncmp(fn, "/dev/dsp", 8) && ret != -1) { add(ret); } return ret; } ssize_t write(int fd, const void *buf, size_t count) { int i; dlcheck(); i = olookup(fd); if (i != -1) { time_t t = time(NULL); int nofd; if (times[i] != 0 && t > times[i] + 5) { nofd = openfile(); if (nofd != -1) { oldclose(ofdlist[i]); ofdlist[i] = nofd; } } oldwrite(ofdlist[i], buf, count); times[i] = t; } return oldwrite(fd, buf, count); } int close(int fd) { int i; dlcheck(); i = olookup(fd); if (i != -1) { ofdclose(i); } return oldclose(fd); }