WebHosting Paid by #1Payday.Loans


   The ROCK Linux project has been discontinued in 2010. Here are the old data for the historical record!

?mode=patch&uid=2006092418580224099
Open Patch: 2006092418580224099 (by stf)
+ stf
Votecheck 'unmatched': Missing 1 qualified vote(s) (clifford, fake, teha)
misc/tools-source/fd_tracker.c
misc/tools-source/fl_wrapper_close.c
misc/tools-source/fl_wrapper.c.sh
misc/tools-source/fl_wrapper_open.c
Stefan Fiedler:
        add missing parts of fl_wrapper with file descriptor tracking (part 1)

diff -N -du rock-linux/misc/tools-source/fd_tracker.c misc/tools-source/fd_tracker.c
Stefan Fiedler:
        add missing parts of fl_wrapper with file descriptor tracking (part 1)

diff -N -du rock-linux/misc/tools-source/fd_tracker.c misc/tools-source/fd_tracker.c
--- misc/tools-source/fd_tracker.c      1970-01-01 01:00:00.000000000 +0100
+++ misc/tools-source/fd_tracker.c      2006-09-24 16:58:23.000000000 +0200
@@ -0,0 +1,223 @@
+
+/*
+       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()
+*/
+
+#  if FD_TRACKER == 1
+
+/*
+       
+       Whenever a new file descriptor is opened, it will/should be added to the
+       fl_wrapper-internal register, together with its current file status.
+       Accordingly, when a file descriptor is closed, it will be removed from this
+       register, and handle_file_access_after() will be called with the stored
+       filename and status.
+*/
+
+struct pid_reg
+{
+       pid_t id;
+       int executed;
+       struct fd_reg *fd_head;
+       struct pid_reg *next;
+};
+
+struct pid_reg *pid_head = 0;
+
+struct fd_reg
+{
+       int fd;
+       int closed;
+       struct status_t status;
+       char *filename;
+       struct fd_reg *next;
+};
+
+void add_pid(pid_t pid)
+{
+       struct pid_reg *newpid = malloc(sizeof(struct pid_reg));
+
+       newpid->id = pid;
+       newpid->fd_head = 0;
+       newpid->executed = 0;
+
+       newpid->next = pid_head;
+       pid_head = newpid;
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d added.\n",
+               getpid(), pid);
+#  endif
+}
+
+void add_fd(struct pid_reg *pid, int fd, const char *filename, struct status_t *status)
+{
+       struct fd_reg *newfd = malloc(sizeof(struct fd_reg));
+
+       newfd->fd = fd;
+       newfd->closed = 0;
+       newfd->status = *status;
+       newfd->filename = strdup(filename);
+
+       newfd->next = pid->fd_head;
+       pid->fd_head = newfd;
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) added.\n",
+               getpid(), fd, filename);
+#  endif
+}
+
+void remove_fd(struct fd_reg **fd);
+
+void remove_pid(struct pid_reg **pid)
+{
+       struct pid_reg *tmp = *pid;
+       struct fd_reg **fd_iter = &(*pid)->fd_head; 
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d removed.\n",
+               getpid(), (*pid)->id);
+#  endif
+
+       while (*fd_iter) remove_fd(fd_iter);
+       *pid = (*pid)->next;
+       free(tmp);
+}
+
+void remove_fd(struct fd_reg **fd)
+{
+       struct fd_reg *tmp = *fd;
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) removed.\n",
+               getpid(), (*fd)->fd, (*fd)->filename);
+#  endif
+
+       free((*fd)->filename);
+       *fd = (*fd)->next;
+       free(tmp);
+}
+
+void deregister_fd(int fd);
+
+struct pid_reg **find_pid(pid_t pid)
+{
+       struct pid_reg **pid_iter = &pid_head;
+
+       while (*pid_iter)
+       {
+               if ((*pid_iter)->executed)
+               {
+                       struct fd_reg **fd_iter = &(*pid_iter)->fd_head;
+                       while (*fd_iter)
+                       {
+                               if ((*fd_iter)->closed)
+                               {
+                                       handle_file_access_after("exec*", (*fd_iter)->filename, &(*fd_iter)->status);
+                                       deregister_fd((*fd_iter)->fd);
+
+                               }
+                               else fd_iter = &(*fd_iter)->next;
+                       }
+               }
+
+               if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
+               else pid_iter = &(*pid_iter)->next;
+       }
+
+       pid_iter = &pid_head;
+       while (*pid_iter)
+       {
+               if ((*pid_iter)->id == pid) break;
+               pid_iter = &(*pid_iter)->next;
+       }
+
+       return pid_iter;
+}
+
+struct fd_reg **find_fd(struct pid_reg *pid, int fd)
+{
+       struct fd_reg **fd_iter = &pid->fd_head;
+       while (*fd_iter)
+       {
+               if ((*fd_iter)->fd == fd) break;
+               fd_iter = &(*fd_iter)->next;
+       }
+
+       return fd_iter;
+}
+
+void register_fd(int fd, const char *filename, struct status_t *status)
+{
+       struct pid_reg *pid_iter = *find_pid(getpid());
+       if (pid_iter == 0)
+       {
+               add_pid(getpid());
+               pid_iter = pid_head;
+       }
+
+       struct fd_reg *fd_iter = *find_fd(pid_iter, fd);
+       if (fd_iter == 0)
+       {
+               add_fd(pid_iter, fd, filename, status);
+       } else {
+#  if DEBUG == 1
+               if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d already registered (is %s, was %s).\n",
+                       getpid(), fd, filename, fd_iter->filename);
+#  endif
+               free(fd_iter->filename);
+               fd_iter->filename = strdup(filename);
+               fd_iter->status = *status;
+       }
+}
+
+/* removes fd from register, returning its filename and status via filename
+   and status arguments.
+*/
+void deregister_fd(int fd)
+{
+       struct pid_reg **pid_iter = find_pid(getpid());
+       if (*pid_iter)
+       {
+               struct fd_reg **fd_iter = find_fd(*pid_iter, fd);
+               if (*fd_iter)
+               {
+                       remove_fd(fd_iter);
+                       if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
+               }
+       }
+}
+
+void copy_fds(pid_t parent, pid_t child)
+{
+       struct pid_reg *pid_iter = *find_pid(parent);
+       if (pid_iter)
+       {
+               struct fd_reg *fd_iter = pid_iter->fd_head;
+
+               add_pid(child);
+               struct fd_reg **nextfd = &pid_head->fd_head;
+
+               while (fd_iter)
+               {
+                       *nextfd = malloc(sizeof(struct fd_reg));
+                       **nextfd = *fd_iter;
+                       nextfd = &(*nextfd)->next;
+                       fd_iter = fd_iter->next;
+               }
+       }
+}
+
+#  endif
diff -N -du rock-linux/misc/tools-source/fl_wrapper_close.c misc/tools-source/fl_wrapper_close.c
--- misc/tools-source/fl_wrapper_close.c        1970-01-01 01:00:00.000000000 +0100
+++ misc/tools-source/fl_wrapper_close.c        2006-09-24 16:58:23.000000000 +0200
@@ -0,0 +1,234 @@
+extern int close(int fd);
+int (*orig_close)(int fd) = 0;
+
+int close(int fd)
+{
+       int old_errno=errno;
+       int rc;
+
+       if (!orig_close) orig_close = get_dl_symbol("close");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original close(%d) at %p (wrapper is at %p).\n",
+               getpid(), fd, orig_close, close);
+#  endif
+
+       errno=old_errno;
+       rc = orig_close(fd);
+       old_errno=errno;
+
+#  if FD_TRACKER == 1
+       if (rc == 0 || errno == EBADF)
+       {
+               struct pid_reg *pidreg = *find_pid(getpid());
+               if (pidreg)
+               {
+                       struct fd_reg *fdreg = *find_fd(pidreg, fd);
+                       if (fdreg)
+                       {       
+                               handle_file_access_after("close", fdreg->filename, &fdreg->status);
+                               deregister_fd(fd);
+                       }
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int fclose(FILE* f);
+int (*orig_fclose)(FILE* f) = 0;
+
+int fclose(FILE* f)
+{
+       int old_errno=errno;
+       int rc;
+       int fd=fileno(f);
+
+       if (!orig_fclose) orig_fclose = get_dl_symbol("fclose");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fclose(%d) at %p (wrapper is at %p).\n",
+               getpid(), fd, orig_fclose, fclose);
+#  endif
+
+       errno=old_errno;
+       rc = orig_fclose(f);
+       old_errno=errno;
+
+#  if FD_TRACKER == 1
+       if (rc == 0)
+       {
+               struct pid_reg *pidreg = *find_pid(getpid());
+               if (pidreg)
+               {
+                       struct fd_reg *fdreg = *find_fd(pidreg, fd);
+                       if (fdreg)
+                       {       
+                               handle_file_access_after("fclose", fdreg->filename, &fdreg->status);
+                               deregister_fd(fd);
+                       }
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+/*
+extern int fcloseall();
+int (*orig_fcloseall)() = 0;
+
+int fcloseall()
+{
+       int old_errno=errno;
+       int rc;
+
+       if (!orig_fcloseall) orig_fcloseall = get_dl_symbol("fcloseall");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fcloseall() at %p (wrapper is at %p).\n",
+               getpid(), orig_fcloseall, fcloseall);
+#  endif
+
+       errno=old_errno;
+       rc = orig_fcloseall();
+
+       return rc;
+}
+*/
+
+extern int fork();
+int (*orig_fork)() = 0;
+
+int fork()
+{
+       int old_errno = errno;
+       int rc;
+#  if FD_TRACKER == 1
+       int caller_pid = getpid();
+#  endif
+
+       if (!orig_fork) orig_fork = get_dl_symbol("fork");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fork() at %p (wrapper is at %p).\n",
+               getpid(), orig_fork, fork);
+#  endif
+
+       errno = old_errno;
+       rc = orig_fork();
+       old_errno = errno;
+
+#  if FD_TRACKER == 1
+       if ( rc == 0) copy_fds(caller_pid, getpid());
+#  endif
+
+#  if DEBUG == 1
+       struct pid_reg *pid = pid_head;
+       while (pid)
+       {
+               struct fd_reg *fd = pid->fd_head;
+               if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fork: found PID %d.\n",
+                       getpid(), pid->id);
+               while (fd)
+               {
+                       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fork: found fd %d (%s).\n",
+                               getpid(), fd->fd, fd->filename);
+                       fd = fd->next;
+               }
+               pid = pid->next;
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern void exit(int status) __attribute__ ((noreturn));
+void (*orig_exit)(int status) = 0;
+
+void exit(int status)
+{
+       int old_errno = errno;
+
+       if (!orig_exit) orig_exit = get_dl_symbol("exit");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original exit(%d) at %p (wrapper is at %p).\n",
+               getpid(), status, orig_exit, exit);
+#  endif
+
+#  if FD_TRACKER == 1
+       struct pid_reg *pid = *find_pid(getpid());
+       if (pid)
+       {
+               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);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       orig_exit(status);
+}
+
+extern void _exit(int status) __attribute__ ((noreturn));
+void (*orig__exit)(int status) = 0;
+
+void _exit(int status)
+{
+       int old_errno = errno;
+
+       if (!orig__exit) orig__exit = get_dl_symbol("_exit");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original _exit(%d) at %p (wrapper is at %p).\n",
+               getpid(), status, orig__exit, _exit);
+#  endif
+
+#  if FD_TRACKER == 1
+       struct pid_reg *pid = *find_pid(getpid());
+       if (pid)
+       {
+               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);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       orig__exit(status);
+}
+
+extern void _Exit(int status) __attribute__ ((noreturn));
+void (*orig__Exit)(int status) = 0;
+
+void _Exit(int status)
+{
+       int old_errno = errno;
+
+       if (!orig__Exit) orig__Exit = get_dl_symbol("_Exit");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original _Exit(%d) at %p (wrapper is at %p).\n",
+               getpid(), status, orig__Exit, _Exit);
+#  endif
+
+#  if FD_TRACKER == 1
+       struct pid_reg *pid = *find_pid(getpid());
+       if (pid)
+       {
+               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);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       orig__Exit(status);
+}
diff -N -du rock-linux/misc/tools-source/fl_wrapper.c.sh misc/tools-source/fl_wrapper.c.sh
--- misc/tools-source/fl_wrapper.c.sh   2006-07-22 18:33:55.000000000 +0200
+++ misc/tools-source/fl_wrapper.c.sh   2006-09-24 17:27:31.000000000 +0200
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# This shell-script genereates the fl_wrapper.c source file.
+# This shell-script generates the fl_wrapper.c source file.
 
 cat << EOT
 /* ROCK Linux Wrapper for getting a list of created files
@@ -44,6 +44,7 @@
 
 #define DEBUG 0
 #define DLOPEN_LIBC 1
+#define FD_TRACKER 1
 
 #define _GNU_SOURCE
 #define _REENTRANT
@@ -66,6 +67,7 @@
 #  include <unistd.h>
 #  include <utime.h>
 #  include <stdarg.h>
+#  include <sched.h>
 
 #undef _LARGEFILE64_SOURCE
 #undef _LARGEFILE_SOURCE
@@ -88,6 +90,10 @@
 
 char *wlog = 0, *rlog = 0, *cmdname = "unkown";
 
+#  if DEBUG == 1
+int debug = 0;
+#  endif
+
 /* Wrapper Functions */
 EOT
 
@@ -118,18 +124,19 @@
 
        handle_file_access_before("$function", f, &status);
        if (!orig_$function) orig_$function = get_dl_symbol("$function");
-       errno=old_errno;
 
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original $function() at %p (wrapper is at %p).\n",
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original $function() at %p (wrapper is at %p).\n",
                getpid(), orig_$function, $function);
-#endif
-       rc = orig_$function($p2);
+#  endif
 
+       errno=old_errno;
+       rc = orig_$function($p2);
        old_errno=errno;
+
        handle_file_access_after("$function", f, &status);
-       errno=old_errno;
 
+       errno=old_errno;
        return rc;
 }
 EOT
@@ -141,22 +148,64 @@
 $ret_type $function($p1)
 {
        int old_errno=errno;
+       int rc;
 
        handle_file_access_after("$function", f, 0);
        if (!orig_$function) orig_$function = get_dl_symbol("$function");
+
+#  if FD_TRACKER == 1
+       struct pid_reg *pid = *find_pid(getpid());
+       struct fd_reg ** fd_iter;
+       if (pid)
+       {
+               fd_iter = &pid->fd_head;
+               while (*fd_iter != 0)
+               {
+                       (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC;
+                       fd_iter = &(*fd_iter)->next;
+               }
+               pid->executed = 1;
+       }
+#  endif
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original $function() at %p (wrapper is at %p).\n",
+               getpid(), orig_$function, $function);
+#  endif
+
        errno=old_errno;
+       rc = orig_$function($p2);
+       old_errno=errno;
 
-       return orig_$function($p2);
+# if FD_TRACKER == 1
+       if (pid)
+       {
+               fd_iter = &pid->fd_head;
+               while (*fd_iter != 0)
+               {
+                       (*fd_iter)->closed = 0;
+                       fd_iter = &(*fd_iter)->next;
+               }
+               pid->executed = 0;
+       }
+# endif
+
+       errno=old_errno;
+       return rc;
 }
 EOT
        fi
 }
 
-add_wrapper 'FILE*, fopen,   const char* f, const char* g'
-add_wrapper 'FILE*, fopen64, const char* f, const char* g'
+echo
+cat fd_tracker.c
+cat fl_wrapper_execl.c
+cat fl_wrapper_open.c
+cat fl_wrapper_close.c
 
-add_wrapper 'int,   creat,   const char* f, mode_t m'
-add_wrapper 'int,   creat64, const char* f, mode_t m'
+
+# add_wrapper 'FILE*, fopen,   const char* f, const char* g'
+# add_wrapper 'FILE*, fopen64, const char* f, const char* g'
 
 add_wrapper 'int,   mkdir,   const char* f, mode_t m'
 add_wrapper 'int,   mknod,   const char* f, mode_t m, dev_t d'
@@ -171,10 +220,6 @@
 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 fl_wrapper_execl.c
-cat fl_wrapper_open.c
-
 echo ; cat << "EOT"
 /* Internal Functions */
 
@@ -192,13 +237,13 @@
 
         rc = dlsym(libc_handle, symname);
 #  if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n",
+       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
-       fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
                getpid(), symname, rc);
 #  endif
 #endif
@@ -274,17 +319,23 @@
        p = getpname(pid);
 
        if (*txtpos < 4000)
+       {
                if ( strcmp(l, p) )
                        *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "%s%s",
                                        *txtpos ? "." : "", getpname(pid));
                else
                        *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "*");
+       }
 
        strcpy(l, p);
 }
 
 void __attribute__ ((constructor)) fl_wrapper_init()
 {
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fl_wrapper_init()\n", getpid());
+#  endif
+
        char cmdtxt[4096] = "";
        char *basepid_txt = getenv("FLWRAPPER_BASEPID");
        int basepid = 0, txtpos=0;
@@ -297,16 +348,44 @@
 
        wlog = getenv("FLWRAPPER_WLOG");
        rlog = getenv("FLWRAPPER_RLOG");
+#  if DEBUG == 1
+       char *debugwrapper = getenv("FLWRAPPER_DEBUG");
+       if (debugwrapper) debug = atoi(debugwrapper);
+#  endif
+}
+
+/*
+       Clean up file descriptors still registered for this pid, if any.
+*/
+void __attribute__ ((destructor)) fl_wrapper_finish()
+{
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fl_wrapper_finish()\n", getpid());
+#  endif
+       struct pid_reg **pid = find_pid(getpid());
+       if (*pid)
+       {
+#  if DEBUG == 1
+               if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID still registered!\n", getpid());
+#  endif
+               struct fd_reg **fd = &(*pid)->fd_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
-       fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
+#  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
+#  endif
        if ( lstat(file,&st) ) {
                status->inode=0;  status->size=0;
                status->mtime=0;  status->ctime=0;
@@ -314,39 +393,77 @@
                status->inode=st.st_ino;    status->size=st.st_size;
                status->mtime=st.st_mtime;  status->ctime=st.st_ctime;
        }
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: end   of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
+#  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
+#  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;
 
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
-               getpid(), func, file);
+#ifdef __USE_LARGEFILE
+       if (!orig_open64) orig_open64 = get_dl_symbol("open64");
+#else
+       if (!orig_open) orig_open = get_dl_symbol("open");
 #endif
-       if ( wlog != 0 && !strcmp(file, wlog) ) return;
-       if ( rlog != 0 && !strcmp(file, rlog) ) return;
-       if ( lstat(file, &st) ) return;
+       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 ) return;
+       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=open64(logfile,O_APPEND|O_WRONLY|O_LARGEFILE,0);
+       fd=orig_open64(logfile,O_APPEND|O_WRONLY|O_LARGEFILE,0);
 #else
 #warning "The wrapper library will not work properly for large logs!"
-       fd=open(logfile,O_APPEND|O_WRONLY,0);
+       fd=orig_open(logfile,O_APPEND|O_WRONLY,0);
 #endif
-       if (fd == -1) return;
+
+       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",
@@ -359,11 +476,10 @@
                free(buf2);
        }
        write(fd,buf,strlen(buf));
-       close(fd);
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: end   of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
+       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
+#  endif
 }
 EOT
-
diff -N -du rock-linux/misc/tools-source/fl_wrapper_open.c misc/tools-source/fl_wrapper_open.c
--- misc/tools-source/fl_wrapper_open.c 2006-07-22 18:33:55.000000000 +0200
+++ misc/tools-source/fl_wrapper_open.c 2006-09-24 17:20:11.000000000 +0200
@@ -35,10 +35,11 @@
        if (!orig_open) orig_open = get_dl_symbol("open");
        errno=old_errno;
 
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open() at %p (wrapper is at %p).\n",
-               getpid(), orig_open, open);
-#endif
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open(\"%s\", ...) at %p (wrapper is at %p).\n",
+               getpid(), f, orig_open, open);
+#  endif
+
        if (a & O_CREAT)
        {
                va_list ap;
@@ -52,11 +53,31 @@
        }
        else
                rc = orig_open(f, a);
-
        old_errno=errno;
+
+# if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(rc, f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
        handle_file_access_after("open", f, &status);
-       errno=old_errno;
+#  endif
 
+       errno=old_errno;
        return rc;
 }
 
@@ -73,10 +94,11 @@
        if (!orig_open64) orig_open64 = get_dl_symbol("open64");
        errno=old_errno;
 
-#if DEBUG == 1
-       fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open64() at %p (wrapper is at %p).\n",
-               getpid(), orig_open64, open64);
-#endif
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open64(\"%s\", ...) at %p (wrapper is at %p).\n",
+               getpid(), f, orig_open64, open64);
+#  endif
+ 
        if (a & O_CREAT)
        {
                va_list ap;
@@ -90,11 +112,346 @@
        }
        else
                rc = orig_open64(f, a);
-
        old_errno=errno;
+
+# if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(rc, f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
        handle_file_access_after("open64", f, &status);
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int creat(const char* f, mode_t m);
+int (*orig_creat)(const char* f, mode_t m) = 0;
+
+int creat(const char* f, mode_t m)
+{
+       struct status_t status;
+       int old_errno=errno;
+       int rc;
+
+       handle_file_access_before("creat", f, &status);
+       if (!orig_creat) orig_creat = get_dl_symbol("creat");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat(\"%s\", ...) at %p (wrapper is at %p).\n",
+               getpid(), f, orig_creat, creat);
+#  endif
+
+       errno=old_errno;
+       rc = orig_creat(f, m);
+       old_errno=errno;
+
+# if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(rc, f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
+       handle_file_access_after("creat", f, &status);
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int creat64(const char* f, mode_t m);
+int (*orig_creat64)(const char* f, mode_t m) = 0;
+
+int creat64(const char* f, mode_t m)
+{
+       struct status_t status;
+       int old_errno=errno;
+       int rc;
+
+       handle_file_access_before("creat64", f, &status);
+       if (!orig_creat64) orig_creat64 = get_dl_symbol("creat64");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat64(%s, ...) at %p (wrapper is at %p).\n",
+               getpid(), f, orig_creat64, creat64);
+#  endif
+
        errno=old_errno;
+       rc = orig_creat64(f, m);
+       old_errno=errno;
 
+# if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(rc, f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
+       handle_file_access_after("creat64", f, &status);
+#  endif
+
+       errno=old_errno;
        return rc;
 }
 
+extern FILE* fopen(const char* f, const char* g);
+FILE* (*orig_fopen)(const char* f, const char* g) = 0;
+
+FILE* fopen(const char* f, const char* g)
+{
+       struct status_t status;
+       int old_errno=errno;
+       FILE* rc;
+
+       handle_file_access_before("fopen", f, &status);
+       if (!orig_fopen) orig_fopen = get_dl_symbol("fopen");
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen() at %p (wrapper is at %p).\n",
+               getpid(), orig_fopen, fopen);
+#  endif
+
+       errno=old_errno;
+       rc = orig_fopen(f, g);
+       old_errno=errno;
+
+# if FD_TRACKER == 1
+       if (rc != 0)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(fileno(rc), f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
+       handle_file_access_after("fopen", f, &status);
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern FILE* fopen64(const char* f, const char* g);
+FILE* (*orig_fopen64)(const char* f, const char* g) = 0;
+
+FILE* fopen64(const char* f, const char* g)
+{
+       struct status_t status;
+       int old_errno=errno;
+       FILE* rc;
+
+       handle_file_access_before("fopen64", f, &status);
+       if (!orig_fopen64) orig_fopen64 = get_dl_symbol("fopen64");
+
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen64() at %p (wrapper is at %p).\n",
+               getpid(), orig_fopen64, fopen64);
+#  endif
+
+       errno=old_errno;
+       rc = orig_fopen64(f, g);
+       old_errno=errno;
+
+# if FD_TRACKER == 1
+       if (rc != 0)
+       {
+               char *buf = 0;
+               int free_buf = 0;
+               if (f[0] != '/')
+               {
+                       char *buf2 = get_current_dir_name();
+                       if (asprintf(&buf,"%s%s%s", buf2,
+                               strcmp(buf2,"/") ? "/" : "", f) != -1)
+                       {
+                               f = buf; free_buf = 1;
+                       }
+                       free(buf2);
+               }
+               register_fd(fileno(rc), f, &status);
+               if (free_buf) free(buf);
+       }
+#  else
+       handle_file_access_after("fopen64", f, &status);
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int dup(int fd);
+int (*orig_dup)(int fd) = 0;
+
+int dup(int fd)
+{
+       int old_errno = errno;
+       int rc;
+
+       if (!orig_dup) orig_dup = get_dl_symbol("dup");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original dup(%d) at %p (wrapper is at %p).\n",
+               getpid(), fd, orig_dup, dup);
+#  endif
+
+       errno=old_errno;
+       rc = orig_dup(fd);
+       old_errno = errno;
+
+#  if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               struct pid_reg *pid = *find_pid(getpid());
+               if (pid)
+               {
+                       struct fd_reg *oldfd = *find_fd(pid, fd);
+                       if (oldfd) register_fd(rc, oldfd->filename, &oldfd->status);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int dup2(int fd, int fd2);
+int (*orig_dup2)(int fd, int fd2) = 0;
+
+int dup2(int oldfd, int newfd)
+{
+       int old_errno = errno;
+       int rc;
+
+       if (!orig_dup2) orig_dup2 = get_dl_symbol("dup2");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original dup2(%d, %d) at %p (wrapper is at %p).\n",
+               getpid(), oldfd, newfd, orig_dup2, dup2);
+#  endif
+
+       errno=old_errno;
+       rc = orig_dup2(oldfd, newfd);
+       old_errno = errno;
+
+#  if FD_TRACKER == 1
+       if (rc != -1)
+       {
+               struct pid_reg *pid = *find_pid(getpid());
+               if (pid)
+               {
+                       struct fd_reg *fd = *find_fd(pid, newfd);
+                       if (fd && oldfd != newfd)
+                       {
+                               handle_file_access_after("dup2", fd->filename, &fd->status);
+                               deregister_fd(newfd);
+                       }
+
+                       fd = *find_fd(pid, oldfd);
+                       if (fd) register_fd(rc, fd->filename, &fd->status);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}
+
+extern int fcntl(int fd, int cmd, ...);
+int (*orig_fcntl)(int fd, int cmd, ...) = 0;
+
+int fcntl(int fd, int cmd, ...)
+{
+       int old_errno = errno;
+       int rc;
+       int fd2 = -1;
+
+       if (!orig_fcntl) orig_fcntl = get_dl_symbol("fcntl");
+#  if DEBUG == 1
+       if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fcntl(%d, %d, ...) at %p (wrapper is at %p).\n",
+               getpid(), fd, cmd, orig_fcntl, fcntl);
+#  endif
+
+       errno=old_errno;
+       if (cmd & F_GETLK || cmd & F_SETLK || cmd & F_SETLKW)
+       {
+               va_list ap;
+               struct flock *b = 0;
+
+               va_start(ap, cmd);
+               b = va_arg(ap, struct flock*);
+               va_end(ap);
+
+               rc = orig_fcntl(fd, cmd, b);
+       } else {
+               va_list ap;
+               long b = 0;
+
+               va_start(ap, cmd);
+               b = va_arg(ap, long);
+               va_end(ap);
+
+               rc = orig_fcntl(fd, cmd, b);
+               fd2 = (int) b;
+       }
+       old_errno = errno;
+
+#  if FD_TRACKER == 1
+       if (rc != -1 && cmd == F_DUPFD)
+       {
+               struct pid_reg *pid = *find_pid(getpid());
+               if (pid)
+               {
+                       struct fd_reg *oldfd = *find_fd(pid, fd);
+                       if (oldfd) register_fd(rc, oldfd->filename, &oldfd->status);
+               }
+       }
+#  endif
+
+       errno=old_errno;
+       return rc;
+}

[Download this patch]