in reply to mocking or trapping system calls
I don't think there's a pure Perl solution... However, you could try to intercept the underlying execvp library function call (at least on unix-ish systems — I think Windows uses spawn). Then, in your wrapper function you could decide what to do, e.g. return fake results, or just pass through to the real function... I know this is highly platform dependent, ugly and probably otherwise tricky in a number of ways... but anyhow, these would be the basic steps — just to illustrate the idea... (quite a number of issues remain to be solved!)
Demo perl program
#!/usr/bin/perl system "/bin/echo", "hello"; # or # system "/bin/echo hello"; # or # my $out = `/bin/echo hello`;
This is the sample wrapper library, which does nothing except printing a message to stderr, and then forwarding the call to the original library function:
/* fakesys.c */ #include <unistd.h> /* for execvp */ #include <dlfcn.h> /* for dlsym */ #include <stdio.h> static int (*real_execvp)(const char *file, char *const argv[]); int execvp(const char *file, char *const argv[]) { char *msg; /* lookup original shared lib function */ real_execvp = dlsym(RTLD_NEXT, "execvp"); /* see dlsym(3) */ if ( (msg = dlerror() ) != NULL ) { fprintf(stderr, "dlopen of execvp() failed : %s\n", msg); } fprintf(stderr, "calling execvp(\"%s\", ...)\n", file); /* execute original lib function */ return real_execvp(file, argv); }
Compile a shared lib (on Linux):
$ gcc -D_GNU_SOURCE -fPIC -shared fakesys.c -o libfakesys.so
and call the program with the intercepted execvp call, using the LD_PRELOAD mechanism (—> "man ld-linux.so"):
$ LD_PRELOAD=./libfakesys.so perl ./685699.pl
Output:
calling execvp("/bin/echo", ...) hello
You get the idea... :)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: mocking or trapping system calls
by Anonymous Monk on May 10, 2008 at 19:44 UTC |