diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-10-26 02:48:01 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-10-26 02:48:01 -0400 |
commit | 3f69c91a73c8813fca6ac1d305dc0c72a21cbb5b (patch) | |
tree | 49015d7227aea9dfd7d10844109f37455b4840b6 /tests/dlopen.c | |
parent | libsandbox: rewrite RTLD_NEXT handling (diff) | |
download | sandbox-3f69c91a73c8813fca6ac1d305dc0c72a21cbb5b.tar.gz sandbox-3f69c91a73c8813fca6ac1d305dc0c72a21cbb5b.tar.bz2 sandbox-3f69c91a73c8813fca6ac1d305dc0c72a21cbb5b.zip |
tests: add simple dlfcn utilv2.2
Simple command line front end to dlopen and friends to quickly test things.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'tests/dlopen.c')
-rw-r--r-- | tests/dlopen.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/dlopen.c b/tests/dlopen.c new file mode 100644 index 0000000..3b62f6c --- /dev/null +++ b/tests/dlopen.c @@ -0,0 +1,109 @@ +/* By Mike Frysinger <vapier@gentoo.org>; released into public domain */ + +#define _GNU_SOURCE +#include <dlfcn.h> +#include <err.h> +#include <stdio.h> +#include <string.h> + +#define FAIL(fmt, args...) errx(1, fmt, ## args) + +static void *xdlopen(char *lib, int flag) +{ + void *hdl; + if (!strcmp(lib, "RTLD_DEFAULT")) + hdl = RTLD_DEFAULT; + else if (!strcmp(lib, "RTLD_NEXT")) + hdl = RTLD_NEXT; + else { + hdl = dlopen(lib, flag); + if (!hdl) + FAIL("dlopen(\"%s\") failed: %s", lib, dlerror()); + } + printf("dlopen(\"%s\") returned %p\n", lib, hdl); + return hdl; +} + +static int xdlclose(void *hdl) +{ + if (hdl != RTLD_DEFAULT && hdl != RTLD_NEXT) { + if (dlclose(hdl)) + FAIL("dlcose() failed: %s", dlerror()); + printf("dlclose(%p) worked\n", hdl); + } else + printf("dlclose() not needed for RTLD_{DEFAULT,NEXT}\n"); + return 0; +} + +static void *xdlsym(void *hdl, char *sym) +{ + void *sym_hdl = dlsym(hdl, sym); + if (!sym_hdl) + FAIL("dlsym(\"%s\") failed: %s", sym, dlerror()); + printf("dlsym(\"%s\") returned %p\n", sym, sym_hdl); + return sym_hdl; +} + +static void *xdlvsym(void *hdl, char *sym, char *ver) +{ + void *sym_hdl = dlvsym(hdl, sym, ver); + if (!sym_hdl) + FAIL("dlvsym(\"%s\", \"%s\") failed: %s", sym, ver, dlerror()); + printf("dlvsym(\"%s\", \"%s\") returned %p\n", sym, ver, sym_hdl); + return sym_hdl; +} + +static int do_dlopen(int argc, char *argv[]) +{ + char *lib = argv[1]; + if (!lib) + FAIL("Usage: dlopen <lib name|RTLD_DEFAULT|RTLD_NEXT>"); + + void *hdl = xdlopen(lib, RTLD_LAZY); + + return xdlclose(hdl); +} + +static int do_dlsym(int argc, char *argv[]) +{ + if (argc != 3) + FAIL("Usage: dlsym <lib name|RTLD_DEFAULT|RTLD_NEXT> <sym>"); + + char *lib = argv[1]; + char *hdl = xdlopen(lib, RTLD_LAZY); + + char *sym = argv[2]; + /* void *sym_hdl = */ xdlsym(hdl, sym); + + return xdlclose(hdl); +} + +static int do_dlvsym(int argc, char *argv[]) +{ + if (argc != 4) + FAIL("Usage: dlvsym <lib name|RTLD_DEFAULT|RTLD_NEXT> <sym> <version>"); + + char *lib = argv[1]; + char *hdl = xdlopen(lib, RTLD_LAZY); + + char *sym = argv[2]; + char *ver = argv[3]; + /* void *sym_hdl = */ xdlvsym(hdl, sym, ver); + + return xdlclose(hdl); +} + +int main(int argc, char *argv[]) +{ + int ret; + char *argv0 = strrchr(argv[0], '/'); + argv0 = argv0 ? argv0 + 1 : argv[0]; + if (!strcmp(argv0, "dlsym")) + ret = do_dlsym(argc, argv); + else if (!strcmp(argv0, "dlvsym")) + ret = do_dlvsym(argc, argv); + else + ret = do_dlopen(argc, argv); + printf("%1$s: all tests %1$sED\n", ret ? "FAIL" : "PASS"); + return ret; +} |