175 lines
3.8 KiB
C++
175 lines
3.8 KiB
C++
// compile with: g++ -rdynamic -std=c++11 -shared -o trace.so trace.cpp getgetCaller().c_str().cpp -fpic -ldl
|
|
|
|
|
|
#define RTLD_NEXT ((void *) -1l)
|
|
#include <dlfcn.h>
|
|
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
#include <string>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#define O_WRONLY 01
|
|
#define O_CREAT 0100
|
|
#define O_TRUNC 01000
|
|
// #include <fcntl.h> // conflicts with open()
|
|
|
|
static int (*libc_open)(const char* path, int flags, mode_t mode) = NULL;
|
|
static int (*libc_close)(int fd) = NULL;
|
|
static int (*libc_socket)(int domain, int type, int protocol) = NULL;
|
|
static int (*libc_accept)(int sockfd, struct sockaddr *addr, socklen_t *addrlen) = NULL;
|
|
static int (*libc_accept4)(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) = NULL;
|
|
|
|
static int (*libc_pipe)(int pipefd[2]) = NULL;
|
|
static int (*libc_pipe2)(int pipefd[2], int flags) = NULL;
|
|
|
|
static int (*libc_dup)(int oldfd) = NULL;
|
|
static int (*libc_dup2)(int oldfd, int newfd) = NULL;
|
|
static int (*libc_dup3)(int oldfd, int newfd, int flags) = NULL;
|
|
|
|
static int writefd = -1;
|
|
|
|
std::string getCaller();
|
|
|
|
#define SETCAST(N) libc_ ## N = ( decltype(libc_ ## N) ) dlsym(RTLD_NEXT, #N)
|
|
|
|
void init() {
|
|
if(!libc_open) {
|
|
SETCAST(open);
|
|
SETCAST(close);
|
|
SETCAST(socket);
|
|
SETCAST(accept);
|
|
SETCAST(accept4);
|
|
SETCAST(pipe);
|
|
SETCAST(pipe2);
|
|
SETCAST(dup);
|
|
SETCAST(dup2);
|
|
SETCAST(dup3);
|
|
|
|
char* target = getenv("TRACEOUT");
|
|
if(!target) {
|
|
writefd = STDOUT_FILENO;
|
|
return;
|
|
}
|
|
|
|
writefd = libc_open(target, (int) O_WRONLY | O_CREAT | O_TRUNC, (mode_t) 0664);
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
int open(const char* path, int flags, mode_t mode) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_open(path, flags, mode);
|
|
|
|
dprintf(writefd, "%s -> open(\"%s\", %i, %o) = %i (e: %i)\n", getCaller().c_str(), path, flags, mode, res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int close(int fd) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_close(fd);
|
|
|
|
dprintf(writefd, "%s -> close(%i) = %i (e: %i)\n", getCaller().c_str(), fd, res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int socket(int dom, int type, int prot) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_socket(dom, type, prot);
|
|
|
|
dprintf(writefd, "%s -> socket(%i, %i, %i) = %i (e: %i)\n", getCaller().c_str(), dom, type, prot, res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_accept(sockfd, addr, addrlen);
|
|
|
|
dprintf(writefd, "%s -> accept(%i, x, x) = %i (e: %i)\n", getCaller().c_str(), sockfd, res, errno);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_accept4(sockfd, addr, addrlen, flags);
|
|
|
|
dprintf(writefd, "%s -> accept4(%i, x, x, %i) = %i (e: %i)\n", getCaller().c_str(), sockfd, flags, res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int pipe(int pipefd[2]) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_pipe(pipefd);
|
|
|
|
dprintf(writefd, "%s -> pipe([%i, %i]) = %i (e: %i)\n", getCaller().c_str(), pipefd[0], pipefd[1], res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int pipe2(int pipefd[2], int flags) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_pipe2(pipefd, flags);
|
|
|
|
dprintf(writefd, "%s -> pipe2([%i, %i], %i) = %i (e: %i)\n", getCaller().c_str(), pipefd[0], pipefd[1], flags, res, errno);
|
|
|
|
return res;
|
|
}
|
|
|
|
int dup(int oldfd) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_dup(oldfd);
|
|
|
|
dprintf(writefd, "%s -> dup(%i) = %i (e: %i)\n", getCaller().c_str(), oldfd, res, errno);
|
|
return res;
|
|
}
|
|
|
|
int dup2(int oldfd, int newfd) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_dup2(oldfd, newfd);
|
|
|
|
dprintf(writefd, "%s -> dup2(%i, %i) = %i (e: %i)\n", getCaller().c_str(), oldfd, newfd, res, errno);
|
|
return res;
|
|
}
|
|
|
|
int dup3(int oldfd, int newfd, int flags) {
|
|
init();
|
|
|
|
errno = 0;
|
|
int res = libc_dup3(oldfd, newfd, flags);
|
|
|
|
dprintf(writefd, "%s -> dup3(%i, %i, %i) = %i (e: %i)\n", getCaller().c_str(), oldfd, newfd, flags, res, errno);
|
|
return res;
|
|
}
|
|
|
|
}
|