I am looking for a way to be able to redefine a set of POSIX functions but then end the redefinition with a call to the original function. The idea is that I am trying to create a layer that can restrict what OS API's can be called depending on which "profile" is active. This "profile" determines what set of functions are allowed and any not specified should not be used.
For example, if in one profile I am not allowed to use strcpy, I would like to be able to either cause a compile time error (via static_assert) or print something to the screen saying "strcpy is not allowed in this profile" such as below:
MY_string.h
#include <string.h>
char *strcpy(char *restrict s1, const char *restrict s2)
{
#if defined(PROFILE_PASS_THROUGH)
printf("strcpy is not allowed in this profile\n");
return strcpy(s1, s2);
#elif defined(PROFILE_ERROR)
static_assesrt(0, "strcpy is not allowed in this profile\n");
return 0;
#else
return strcpy(s1, s2);
#endif
}
So that way within main.cpp I can use MY_string.h
#define PROFILE_PASS_THROUGH
#include "MY_string.h"
int main()
{
char temp1[10];
char temp2[10];
sprintf(temp2, "Testing");
if (0 = strcpy(temp1, temp2))
{
printf("temp1 is %s\n", temp1);
}
return 0;
}
Now I realize that the code I have written above will not compile properly due to the redefinition of strcpy, but is there a way to allow this sort of functionality without playing around with macros or creating my own standard c and c++ libraries?
You can write a preprocessor that changes calls to the standard routine to calls to your own routine. Such a preprocessor might be complicated, depending whether you need to recognize the full C++ grammar to distinguish calls using name spaces and so on or you can get away with more casual recognition of the calls.
You can link with your own library, producing a relocatable object module with resolved names stripped. Your library would contain routines with the standard names, such as
strcpy
, that execute whatever code you desire and call other names, such asMystrcpy
. The object module produced by this is then linked with a second library and with the standard library. The second library contains routines with those names, such asMystrcpy
, that call the original library namesstrcpy
. The details for doing this are of course dependent on your linker. The goal is to have a chain like this: Original code callsstrcpy
. This is resolved to the version ofstrcpy
in the first library. That version callsMystrcpy
.Mystrcpy
calls the standard librarystrcpy
.You can compile to assembly and edit the names in the assembly so that your routines are called instead of the standard library routines.
On some systems, you can use
dlsym
and other functions defined in<dlfcn.h>
to load the dynamic library that contains the standard implementations and to call them via pointers returned bydlsym
instead of by the usual names in source code.The GCC linker has a
--wrap
switch that resolves calls tofoo
to your routine__wrap_foo
and resolves calls to__real_foo
(which you would use in your implementation) to the realfoo
.See also Intercepting Arbitrary Functions on Windows, UNIX, and Macintosh OS X Platforms.