X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libinterfork%2Finterfork.c;h=e9dce9bfb188d7f60032d04a5f2b9d9dfd5f9f2b;hb=fbca6b624335eef18c8d86194aeb101a720168f4;hp=e57b7e593c06664a5cf73313185ef6cea3462935;hpb=2d99476b851d50b376bafb2bc12994d8b0950538;p=ust.git diff --git a/libinterfork/interfork.c b/libinterfork/interfork.c index e57b7e5..e9dce9b 100644 --- a/libinterfork/interfork.c +++ b/libinterfork/interfork.c @@ -19,6 +19,11 @@ #include #include #include +#include +#include "usterr.h" + +extern void ust_fork(void); +extern void ust_potential_exec(void); pid_t fork(void) { @@ -26,19 +31,71 @@ 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) { fprintf(stderr, "libcwrap: unable to find fork\n"); - return NULL; + return -1; } } - printf("IN FORK!\n"); + /* 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; }