|
...making Linux just a little more fun! |
By Tom Bradley |
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#define PATH_LENGTH 256
int main(int argc, char * argv[])
{
char path[PATH_LENGTH], * msg = NULL;
int (*my_entry)();
void * module;
/* build the pathname for the module */
getcwd(path, PATH_LENGTH);
strcat(path, "/");
strcat(path, argv[1]);
/* load the module, and resolve symbols now */
module = dlopen(path, RTLD_NOW);
if(!module) {
msg = dlerror();
if(msg != NULL) {
dlclose(module);
exit(1);
}
}
/* retrieve address of entry point */
my_entry = dlsym(module, "entry");
msg = dlerror();
if(msg != NULL) {
perror(msg);
dlclose(module);
exit(1);
}
/* call module entry point */
my_entry();
/* close module */
if(dlclose(module)) {
perror("error");
exit(1);
}
return 0;
}
|
$ gcc -o loader main.c –ldl |
int entry()
{
printf("I am module one!\n");
return 0;
}
|
int entry()
{
printf("I am module two!\n");
return 0;
}
|
$ gcc -fPIC -c module1.c $ gcc -shared -o module1.so module1.o $ gcc -fPIC -c module2.c $ gcc -shared -o module2.so module2.o |
$ ./loader module1.so I am module one! $ ./loader module2.so I am module two! |
__attribute__ ((constructor)) void init()
{
/* code here is executed after dlopen() has loaded the module */
}
__attribute__ ((destructor)) void fini()
{
/* code here is executed just before dlclose() unloads the module */
}
|