From 14323571cab7ad58d70ecd73878034c0664714a2 Mon Sep 17 00:00:00 2001 From: Stefan Fiedler Date: Fri, 2 Nov 2007 13:21:31 +0000 Subject: [PATCH] Stefan Fiedler: fl_wrapper: get rid of compiler warnings; enable support for on-demand debug output fix segmentation faults in some glibc tests move internal functions to separate file [2007091121181421883] (https://www.rocklinux.net/submaster) git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@8714 c5f82cb5-29bc-0310-9cd0-bff59a50e3bc --- misc/tools-source/fd_tracker.c | 10 - misc/tools-source/fl_wrapper.c | 82 +++---- misc/tools-source/fl_wrapper.c.sh | 274 +----------------------- misc/tools-source/fl_wrapper_close.c | 41 ++-- misc/tools-source/fl_wrapper_internal.c | 268 +++++++++++++++++++++++ scripts/Build-Tools | 3 +- 6 files changed, 347 insertions(+), 331 deletions(-) create mode 100644 misc/tools-source/fl_wrapper_internal.c diff --git a/misc/tools-source/fd_tracker.c b/misc/tools-source/fd_tracker.c index d79d17091..2951e13a9 100644 --- a/misc/tools-source/fd_tracker.c +++ b/misc/tools-source/fd_tracker.c @@ -1,15 +1,5 @@ /* - TODO: - get rid of the compiler warnings: - -fl_wrapper.c: In function '_Exit': -fl_wrapper.c:1100: warning: 'noreturn' function does return -fl_wrapper.c: In function '_exit': -fl_wrapper.c:1075: warning: 'noreturn' function does return -fl_wrapper.c: In function 'exit': -fl_wrapper.c:1050: warning: 'noreturn' function does return - maybe TODO: wrape clone(); catch termination of child process created with clone() */ diff --git a/misc/tools-source/fl_wrapper.c b/misc/tools-source/fl_wrapper.c index 172cf645a..8fce3d796 100644 --- a/misc/tools-source/fl_wrapper.c +++ b/misc/tools-source/fl_wrapper.c @@ -37,7 +37,7 @@ /* Headers and prototypes */ -#define DEBUG 0 +#define DEBUG 1 #define DLOPEN_LIBC 1 #define FD_TRACKER 1 @@ -93,16 +93,6 @@ int debug = 0; /* - TODO: - get rid of the compiler warnings: - -fl_wrapper.c: In function '_Exit': -fl_wrapper.c:1100: warning: 'noreturn' function does return -fl_wrapper.c: In function '_exit': -fl_wrapper.c:1075: warning: 'noreturn' function does return -fl_wrapper.c: In function 'exit': -fl_wrapper.c:1050: warning: 'noreturn' function does return - maybe TODO: wrape clone(); catch termination of child process created with clone() */ @@ -1203,7 +1193,8 @@ int fork() if ( rc == 0) copy_fds(caller_pid, getpid()); # endif -# if DEBUG == 1 +# if FD_TRACKER == 1 +# if DEBUG == 1 struct pid_reg *pid = pid_head; while (pid) { @@ -1218,14 +1209,14 @@ int fork() } pid = pid->next; } +# endif # endif - errno=old_errno; return rc; } extern void exit(int status) __attribute__ ((noreturn)); -void (*orig_exit)(int status) = 0; +void (*orig_exit)(int status) __attribute__ ((noreturn)) = 0; void exit(int status) { @@ -1241,11 +1232,13 @@ void exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif @@ -1255,7 +1248,7 @@ void exit(int status) } extern void _exit(int status) __attribute__ ((noreturn)); -void (*orig__exit)(int status) = 0; +void (*orig__exit)(int status) __attribute__ ((noreturn)) = 0; void _exit(int status) { @@ -1271,11 +1264,13 @@ void _exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("_exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("_exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif @@ -1285,7 +1280,7 @@ void _exit(int status) } extern void _Exit(int status) __attribute__ ((noreturn)); -void (*orig__Exit)(int status) = 0; +void (*orig__Exit)(int status) __attribute__ ((noreturn)) = 0; void _Exit(int status) { @@ -1301,11 +1296,13 @@ void _Exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("_Exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("_Exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif @@ -1503,6 +1500,8 @@ int utimes(const char* f, struct timeval* t) return rc; } +extern int fcntl(int fd, int cmd, ...); + extern int execv(const char* f, char* const a[]); int (*orig_execv)(const char* f, char* const a[]) = 0; @@ -1513,6 +1512,7 @@ int execv(const char* f, char* const a[]) handle_file_access_after("execv", f, 0); if (!orig_execv) orig_execv = get_dl_symbol("execv"); + if (!orig_fcntl) orig_fcntl = get_dl_symbol("fcntl"); # if FD_TRACKER == 1 struct pid_reg *pid = *find_pid(getpid()); @@ -1522,7 +1522,7 @@ int execv(const char* f, char* const a[]) fd_iter = &pid->fd_head; while (*fd_iter != 0) { - (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; + (*fd_iter)->closed = orig_fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; fd_iter = &(*fd_iter)->next; } pid->executed = 1; @@ -1555,6 +1555,8 @@ int execv(const char* f, char* const a[]) return rc; } +extern int fcntl(int fd, int cmd, ...); + extern int execve(const char* f, char* const a[], char* const e[]); int (*orig_execve)(const char* f, char* const a[], char* const e[]) = 0; @@ -1565,6 +1567,7 @@ int execve(const char* f, char* const a[], char* const e[]) handle_file_access_after("execve", f, 0); if (!orig_execve) orig_execve = get_dl_symbol("execve"); + if (!orig_fcntl) orig_fcntl = get_dl_symbol("fcntl"); # if FD_TRACKER == 1 struct pid_reg *pid = *find_pid(getpid()); @@ -1574,7 +1577,7 @@ int execve(const char* f, char* const a[], char* const e[]) fd_iter = &pid->fd_head; while (*fd_iter != 0) { - (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; + (*fd_iter)->closed = orig_fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; fd_iter = &(*fd_iter)->next; } pid->executed = 1; @@ -1642,19 +1645,24 @@ static void * get_dl_symbol(char * symname) return rc; } +extern int open(const char* f, int a, ...); + static int pid2ppid(int pid) { char buffer[100]; int fd, rc, ppid = 0; + if (!orig_open) orig_open = get_dl_symbol("open"); + if (!orig_close) orig_close = get_dl_symbol("close"); + sprintf(buffer, "/proc/%d/stat", pid); - if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return 0; + if ( (fd = orig_open(buffer, O_RDONLY, 0)) < 0 ) return 0; if ( (rc = read(fd, buffer, 99)) > 0) { buffer[rc] = 0; /* format: 27910 (bash) S 27315 ... */ sscanf(buffer, "%*[^ ] %*[^ ] %*[^ ] %d", &ppid); } - close(fd); + orig_close(fd); return ppid; } @@ -1669,14 +1677,14 @@ static char *getpname(int pid) int i, fd, rc; sprintf(buffer, "/proc/%d/cmdline", pid); - if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return "unkown"; + if ( (fd = orig_open(buffer, O_RDONLY, 0)) < 0 ) return "unkown"; if ( (rc = read(fd, buffer, 512)) > 0) { buffer[rc--] = 0; for (i=0; ifd_head; while (*fd) { @@ -1762,6 +1771,7 @@ void __attribute__ ((destructor)) fl_wrapper_finish() } remove_pid(pid); } +# endif } static void handle_file_access_before(const char * func, const char * file, diff --git a/misc/tools-source/fl_wrapper.c.sh b/misc/tools-source/fl_wrapper.c.sh index c4aa6755d..59455f0fe 100644 --- a/misc/tools-source/fl_wrapper.c.sh +++ b/misc/tools-source/fl_wrapper.c.sh @@ -42,7 +42,7 @@ cat << EOT /* Headers and prototypes */ -#define DEBUG 0 +#define DEBUG 1 #define DLOPEN_LIBC 1 #define FD_TRACKER 1 @@ -107,7 +107,7 @@ add_wrapper() ret_type=$1 ; shift ; function=$1 ; shift p1="" ; p2="" ; for x ; do p1="$p1$x, " ; done - for x ; do x="${x%%\[\]}" ; p2="$p2${x##* }, " ; done + for x ; do x="${x%%'[]'}" ; p2="$p2${x##* }, " ; done p1="${p1%, }" ; p2="${p2%, }" if [ "${function#exec}" = "${function}" ] @@ -142,6 +142,8 @@ $ret_type $function($p1) EOT else echo ; cat << EOT +extern int fcntl(int fd, int cmd, ...); + extern $ret_type $function($p1); $ret_type (*orig_$function)($p1) = 0; @@ -152,6 +154,7 @@ $ret_type $function($p1) handle_file_access_after("$function", f, 0); if (!orig_$function) orig_$function = get_dl_symbol("$function"); + if (!orig_fcntl) orig_fcntl = get_dl_symbol("fcntl"); # if FD_TRACKER == 1 struct pid_reg *pid = *find_pid(getpid()); @@ -161,7 +164,7 @@ $ret_type $function($p1) fd_iter = &pid->fd_head; while (*fd_iter != 0) { - (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; + (*fd_iter)->closed = orig_fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC; fd_iter = &(*fd_iter)->next; } pid->executed = 1; @@ -220,266 +223,5 @@ add_wrapper 'int, utimes, const char* f, struct timeval* t' add_wrapper 'int, execv, const char* f, char* const a[]' add_wrapper 'int, execve, const char* f, char* const a[], char* const e[]' -echo ; cat << "EOT" -/* Internal Functions */ - -static void * get_dl_symbol(char * symname) -{ - void * rc; -#if DLOPEN_LIBC - static void * libc_handle = 0; - - if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY); - if (!libc_handle) { - printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror()); - abort(); - } - - rc = dlsym(libc_handle, symname); -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n", - getpid(), symname, libc_handle, rc); -# endif -#else - rc = dlsym(RTLD_NEXT, symname); -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n", - getpid(), symname, rc); -# endif -#endif - if (!rc) { - printf("fl_wrapper.so: Can't resolve %s: %s\n", - symname, dlerror()); - abort(); - } - - return rc; -} - -static int pid2ppid(int pid) -{ - char buffer[100]; - int fd, rc, ppid = 0; - - sprintf(buffer, "/proc/%d/stat", pid); - if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return 0; - if ( (rc = read(fd, buffer, 99)) > 0) { - buffer[rc] = 0; - /* format: 27910 (bash) S 27315 ... */ - sscanf(buffer, "%*[^ ] %*[^ ] %*[^ ] %d", &ppid); - } - close(fd); - - return ppid; -} - -/* this is only called from fl_wrapper_init(). so it doesn't need to be - * reentrant. */ -static char *getpname(int pid) -{ - static char p[512]; - char buffer[513]=""; - char *arg=0, *b; - int i, fd, rc; - - sprintf(buffer, "/proc/%d/cmdline", pid); - if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return "unkown"; - if ( (rc = read(fd, buffer, 512)) > 0) { - buffer[rc--] = 0; - for (i=0; ifd_head; - while (*fd) - { - handle_file_access_after("fl_wrapper_finish", (*fd)->filename, &(*fd)->status); - remove_fd(fd); - } - remove_pid(pid); - } -} - -static void handle_file_access_before(const char * func, const char * file, - struct status_t * status) -{ - struct stat st; -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n", - getpid(), func, file); -# endif - if ( lstat(file,&st) ) { - status->inode=0; status->size=0; - status->mtime=0; status->ctime=0; - } else { - status->inode=st.st_ino; status->size=st.st_size; - status->mtime=st.st_mtime; status->ctime=st.st_ctime; - } -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n", - getpid(), func, file); -# endif -} - -/* - Declared in fl_wrapper_open.c and fl_wrapper_close.c, - reused here since logging access to the log files eventually - overwrites close'd but not yet deregistered file descriptors. - -int (*orig_open)(const char* f, int a, ...) = 0; -int (*orig_open64)(const char* f, int a, ...) = 0; -int (*orig_close)(int fd) = 0; -*/ - -static void handle_file_access_after(const char * func, const char * file, - struct status_t * status) -{ - char buf[512], *buf2, *logfile; - int fd; struct stat st; - -#ifdef __USE_LARGEFILE - if (!orig_open64) orig_open64 = get_dl_symbol("open64"); -#else - if (!orig_open) orig_open = get_dl_symbol("open"); -#endif - if (!orig_close) orig_close = get_dl_symbol("close"); -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx), %d, %s, %s\n", - getpid(), func, file, status != 0, wlog, rlog); -# endif - - if ( lstat(file, &st) ) - { -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: lstat(%s, ...) failed\n", - getpid(), file); -# endif - return; - } - - if ( (status != 0) && (status->inode != st.st_ino || - status->size != st.st_size || status->mtime != st.st_mtime || - status->ctime != st.st_ctime) ) { logfile = wlog; } - else { logfile = rlog; } - - if ( logfile == 0 ) - { -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: no log file\n", - getpid()); -# endif - return; - } - -#ifdef __USE_LARGEFILE - fd=orig_open64(logfile,O_APPEND|O_WRONLY|O_LARGEFILE,0); -#else -#warning "The wrapper library will not work properly for large logs!" - fd=orig_open(logfile,O_APPEND|O_WRONLY,0); -#endif - - if (fd == -1) - { -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: log open failed (%s)\n", - getpid(), strerror(errno)); -# endif - return; - } - - if (file[0] == '/') { - sprintf(buf,"%s.%s:\t%s\n", - cmdname, func, file); - } else { - buf2=get_current_dir_name(); - sprintf(buf,"%s.%s:\t%s%s%s\n", - cmdname, func, buf2, - strcmp(buf2,"/") ? "/" : "", file); - free(buf2); - } - write(fd,buf,strlen(buf)); - orig_close(fd); -# if DEBUG == 1 - if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n", - getpid(), func, file); -# endif -} -EOT +echo +cat fl_wrapper_internal.c diff --git a/misc/tools-source/fl_wrapper_close.c b/misc/tools-source/fl_wrapper_close.c index f025a6598..054826e11 100644 --- a/misc/tools-source/fl_wrapper_close.c +++ b/misc/tools-source/fl_wrapper_close.c @@ -122,7 +122,8 @@ int fork() if ( rc == 0) copy_fds(caller_pid, getpid()); # endif -# if DEBUG == 1 +# if FD_TRACKER == 1 +# if DEBUG == 1 struct pid_reg *pid = pid_head; while (pid) { @@ -137,14 +138,14 @@ int fork() } pid = pid->next; } +# endif # endif - errno=old_errno; return rc; } extern void exit(int status) __attribute__ ((noreturn)); -void (*orig_exit)(int status) = 0; +void (*orig_exit)(int status) __attribute__ ((noreturn)) = 0; void exit(int status) { @@ -160,11 +161,13 @@ void exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif @@ -174,7 +177,7 @@ void exit(int status) } extern void _exit(int status) __attribute__ ((noreturn)); -void (*orig__exit)(int status) = 0; +void (*orig__exit)(int status) __attribute__ ((noreturn)) = 0; void _exit(int status) { @@ -190,11 +193,13 @@ void _exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("_exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("_exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif @@ -204,7 +209,7 @@ void _exit(int status) } extern void _Exit(int status) __attribute__ ((noreturn)); -void (*orig__Exit)(int status) = 0; +void (*orig__Exit)(int status) __attribute__ ((noreturn)) = 0; void _Exit(int status) { @@ -220,11 +225,13 @@ void _Exit(int status) struct pid_reg *pid = *find_pid(getpid()); if (pid) { - struct fd_reg **fd_iter = &pid->fd_head; - while (*fd_iter) + struct fd_reg *fd_iter = pid->fd_head; + while (fd_iter) { - handle_file_access_after("_Exit", (*fd_iter)->filename, &(*fd_iter)->status); - deregister_fd((*fd_iter)->fd); + struct fd_reg *new_fd_iter=fd_iter->next; + handle_file_access_after("_Exit", fd_iter->filename, &fd_iter->status); + deregister_fd(fd_iter->fd); + fd_iter=new_fd_iter; } } # endif diff --git a/misc/tools-source/fl_wrapper_internal.c b/misc/tools-source/fl_wrapper_internal.c new file mode 100644 index 000000000..57d2ce831 --- /dev/null +++ b/misc/tools-source/fl_wrapper_internal.c @@ -0,0 +1,268 @@ +/* Internal Functions */ + +static void * get_dl_symbol(char * symname) +{ + void * rc; +#if DLOPEN_LIBC + static void * libc_handle = 0; + + if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY); + if (!libc_handle) { + printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror()); + abort(); + } + + rc = dlsym(libc_handle, symname); +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n", + getpid(), symname, libc_handle, rc); +# endif +#else + rc = dlsym(RTLD_NEXT, symname); +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n", + getpid(), symname, rc); +# endif +#endif + if (!rc) { + printf("fl_wrapper.so: Can't resolve %s: %s\n", + symname, dlerror()); + abort(); + } + + return rc; +} + +extern int open(const char* f, int a, ...); + +static int pid2ppid(int pid) +{ + char buffer[100]; + int fd, rc, ppid = 0; + + if (!orig_open) orig_open = get_dl_symbol("open"); + if (!orig_close) orig_close = get_dl_symbol("close"); + + sprintf(buffer, "/proc/%d/stat", pid); + if ( (fd = orig_open(buffer, O_RDONLY, 0)) < 0 ) return 0; + if ( (rc = read(fd, buffer, 99)) > 0) { + buffer[rc] = 0; + /* format: 27910 (bash) S 27315 ... */ + sscanf(buffer, "%*[^ ] %*[^ ] %*[^ ] %d", &ppid); + } + orig_close(fd); + + return ppid; +} + +/* this is only called from fl_wrapper_init(). so it doesn't need to be + * reentrant. */ +static char *getpname(int pid) +{ + static char p[512]; + char buffer[513]=""; + char *arg=0, *b; + int i, fd, rc; + + sprintf(buffer, "/proc/%d/cmdline", pid); + if ( (fd = orig_open(buffer, O_RDONLY, 0)) < 0 ) return "unkown"; + if ( (rc = read(fd, buffer, 512)) > 0) { + buffer[rc--] = 0; + for (i=0; ifd_head; + while (*fd) + { + handle_file_access_after("fl_wrapper_finish", (*fd)->filename, &(*fd)->status); + remove_fd(fd); + } + remove_pid(pid); + } +# endif +} + +static void handle_file_access_before(const char * func, const char * file, + struct status_t * status) +{ + struct stat st; +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n", + getpid(), func, file); +# endif + if ( lstat(file,&st) ) { + status->inode=0; status->size=0; + status->mtime=0; status->ctime=0; + } else { + status->inode=st.st_ino; status->size=st.st_size; + status->mtime=st.st_mtime; status->ctime=st.st_ctime; + } +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n", + getpid(), func, file); +# endif +} + +/* + Declared in fl_wrapper_open.c and fl_wrapper_close.c, + reused here since logging access to the log files eventually + overwrites close'd but not yet deregistered file descriptors. + +int (*orig_open)(const char* f, int a, ...) = 0; +int (*orig_open64)(const char* f, int a, ...) = 0; +int (*orig_close)(int fd) = 0; +*/ + +static void handle_file_access_after(const char * func, const char * file, + struct status_t * status) +{ + char buf[512], *buf2, *logfile; + int fd; struct stat st; + +#ifdef __USE_LARGEFILE + if (!orig_open64) orig_open64 = get_dl_symbol("open64"); +#else + if (!orig_open) orig_open = get_dl_symbol("open"); +#endif + if (!orig_close) orig_close = get_dl_symbol("close"); +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx), %d, %s, %s\n", + getpid(), func, file, status != 0, wlog, rlog); +# endif + + if ( lstat(file, &st) ) + { +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: lstat(%s, ...) failed\n", + getpid(), file); +# endif + return; + } + + if ( (status != 0) && (status->inode != st.st_ino || + status->size != st.st_size || status->mtime != st.st_mtime || + status->ctime != st.st_ctime) ) { logfile = wlog; } + else { logfile = rlog; } + + if ( logfile == 0 ) + { +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: no log file\n", + getpid()); +# endif + return; + } + +#ifdef __USE_LARGEFILE + fd=orig_open64(logfile,O_APPEND|O_WRONLY|O_LARGEFILE,0); +#else +#warning "The wrapper library will not work properly for large logs!" + fd=orig_open(logfile,O_APPEND|O_WRONLY,0); +#endif + + if (fd == -1) + { +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: log open failed (%s)\n", + getpid(), strerror(errno)); +# endif + return; + } + + if (file[0] == '/') { + sprintf(buf,"%s.%s:\t%s\n", + cmdname, func, file); + } else { + buf2=get_current_dir_name(); + sprintf(buf,"%s.%s:\t%s%s%s\n", + cmdname, func, buf2, + strcmp(buf2,"/") ? "/" : "", file); + free(buf2); + } + write(fd,buf,strlen(buf)); + orig_close(fd); +# if DEBUG == 1 + if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n", + getpid(), func, file); +# endif +} diff --git a/scripts/Build-Tools b/scripts/Build-Tools index 2636d809d..f5df19012 100755 --- a/scripts/Build-Tools +++ b/scripts/Build-Tools @@ -262,8 +262,7 @@ EOT if [ "$ROCKCFG_FLIST" = "flwrapper" ] ; then echo_status "Building $toolsdir/lib/fl_wrapper.so." $BUILDCC -Wall -O2 -ldl -fPIC -shared misc/tools-source/fl_wrapper.c \ - -o build/$ROCKCFG_ID/ROCK/$toolsdir/lib/fl_wrapper.so.$$ \ - 2>/dev/null || exit 1 + -o build/$ROCKCFG_ID/ROCK/$toolsdir/lib/fl_wrapper.so.$$ || exit 1 mv build/$ROCKCFG_ID/ROCK/$toolsdir/lib/fl_wrapper.so.$$ \ build/$ROCKCFG_ID/ROCK/$toolsdir/lib/fl_wrapper.so