Move kernelcompat.h to include/ust/ and share.h, usterr.h to include/
[ust.git] / libinterfork / interfork.c
index 646dbda22f31e826f7ad5205147b831c083c9c5b..e9dce9bfb188d7f60032d04a5f2b9d9dfd5f9f2b 100644 (file)
 #include <dlfcn.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <signal.h>
+#include "usterr.h"
 
 extern void ust_fork(void);
+extern void ust_potential_exec(void);
 
 pid_t fork(void)
 {
@@ -28,6 +31,10 @@ pid_t fork(void)
 
        pid_t retval;
 
+       int result;
+       sigset_t all_sigs;
+       sigset_t orig_sigs;
+
        if(plibc_func == NULL) {
                plibc_func = dlsym(RTLD_NEXT, "fork");
                if(plibc_func == NULL) {
@@ -36,10 +43,59 @@ pid_t fork(void)
                }
        }
 
+       /* Disable interrupts. This is to avoid that the child
+        * intervenes before it is properly setup for tracing. It is
+        * safer to disable all signals, because then we know we are not
+        * breaking anything by restoring the original mask.
+        */
+
+       /* FIXME:
+               - only do this if tracing is active
+       */
+
+       /* Disable signals */
+       sigfillset(&all_sigs);
+       result = sigprocmask(SIG_BLOCK, &all_sigs, &orig_sigs);
+       if(result == -1) {
+               PERROR("sigprocmask");
+               return -1;
+       }
+
+       /* Do the real fork */
        retval = plibc_func();
 
-       if(retval == 0)
+       if(retval == 0) {
+               /* child */
                ust_fork();
+       }
+
+       /* Restore signals */
+       result = sigprocmask(SIG_BLOCK, &orig_sigs, NULL);
+       if(result == -1) {
+               PERROR("sigprocmask");
+               return -1;
+       }
+
+       return retval;
+}
+
+int execve(const char *filename, char *const argv[], char *const envp[])
+{
+       static int (*plibc_func)(const char *filename, char *const argv[], char *const envp[]) = NULL;
+
+       pid_t retval;
+
+       if(plibc_func == NULL) {
+               plibc_func = dlsym(RTLD_NEXT, "execve");
+               if(plibc_func == NULL) {
+                       fprintf(stderr, "libcwrap: unable to find execve\n");
+                       return -1;
+               }
+       }
+
+       ust_potential_exec();
+
+       retval = plibc_func(filename, argv, envp);
 
        return retval;
 }
This page took 0.02374 seconds and 4 git commands to generate.