aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-10-26 02:48:01 -0400
committerMike Frysinger <vapier@gentoo.org>2009-10-26 02:48:01 -0400
commit3f69c91a73c8813fca6ac1d305dc0c72a21cbb5b (patch)
tree49015d7227aea9dfd7d10844109f37455b4840b6
parentlibsandbox: rewrite RTLD_NEXT handling (diff)
downloadsandbox-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>
-rw-r--r--tests/dlopen.c109
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;
+}