#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <getopt.h> | |
#include <string.h> | |
#include <dlfcn.h> | |
extern char *optarg; | |
extern int optind, opterr, optopt; | |
static struct option long_options[] = { | |
{"library", required_argument, 0, 'l'}, | |
{"symbol", required_argument, 0, 's'}, | |
{"help", no_argument, 0, 'h'}, | |
{0, 0, 0, 0}, | |
}; | |
/* This array must parallel long_options[] */ | |
static const char *descriptions[] = { | |
"specify a library path to look up symbol", | |
"specify symbol to look up", | |
"print this help screen", | |
}; | |
void print_help(const char *name) { | |
fprintf(stdout, | |
"invokation:\n" | |
"\t%s [-l <libname>] -s <symbol name>\n" | |
"\t%s -h\n\n", name, name); | |
fprintf(stdout, "options:\n"); | |
struct option *opt = long_options; | |
const char **desc = descriptions; | |
while (opt->name) { | |
fprintf(stdout, "\t-%c/--%s%s: %s\n", | |
opt->val, | |
opt->name, | |
(opt->has_arg ? " (argument)" : ""), | |
*desc); | |
opt++; | |
desc++; | |
} | |
} | |
int get_options(int argc, char **argv, char **lib, char **sym) | |
{ | |
int c; | |
*lib = 0; | |
*sym = 0; | |
while (1) { | |
/* getopt_long stores the option index here. */ | |
int option_index = 0; | |
c = getopt_long (argc, argv, | |
"l:s:h", | |
long_options, | |
&option_index); | |
/* Detect the end of the options. */ | |
if (c == -1) break; | |
switch (c) { | |
case 'l': | |
*lib = strdup(optarg); | |
break; | |
case 's': | |
*sym = strdup(optarg); | |
break; | |
case 'h': print_help(argv[0]); exit(EXIT_FAILURE); break; | |
case '?': | |
/* getopt_long already printed an error message. */ | |
break; | |
default: | |
fprintf(stderr, "Unknown option"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
return optind; | |
} | |
int main(int argc, char **argv) | |
{ | |
char *libname, *symname, *prog = *argv; | |
get_options(argc, argv, &libname, &symname); | |
if (symname == NULL) { | |
fprintf(stderr, "You must specify a symbol!\n"); | |
print_help(prog); | |
exit(EXIT_FAILURE); | |
} | |
{ | |
const char *dlerr; | |
void *handle, *symbol; | |
printf("opening library [%s]\n", libname); | |
dlerr = dlerror(); | |
handle = libname ? dlopen(libname, RTLD_NOW) : RTLD_DEFAULT; | |
dlerr = dlerror(); | |
if (dlerr != NULL) fprintf(stderr, "dlopen() error: %s\n", dlerr); | |
printf("opening symbol [%s]\n", symname); | |
symbol = dlsym(handle, symname); | |
dlerr = dlerror(); | |
if (dlerr != NULL) fprintf(stderr, "dlsym() error: %s\n", dlerr); | |
printf("closing library [%s]\n", libname); | |
dlclose(handle); | |
dlerr = dlerror(); | |
if (dlerr != NULL) fprintf(stderr, "dlclose() error: %s\n", dlerr); | |
else printf("successfully opened symbol\n"); | |
} | |
if (libname != NULL) free(libname); | |
if (symname != NULL) free(symname); | |
return 0; | |
} |