#define _GNU_SOURCE
#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <string.h>
+#include "fips.h"
#include "dlwrap.h"
-#define STRNCMP_LITERAL(var, literal) \
- strncmp ((var), (literal), sizeof (literal) - 1)
-
void *libfips_handle;
typedef void * (* fips_dlopen_t)(const char * filename, int flag);
dlopen (const char *filename, int flag)
{
Dl_info info;
+ void *ret;
+
+ /* Before deciding whether to redirect this dlopen to our own
+ * library, we call the real dlopen. This assures that any
+ * expected side-effects from loading the intended library are
+ * resolved. Below, we may still return a handle pointing to
+ * our own library, and not what is opened here. */
+ ret = dlwrap_real_dlopen (filename, flag);
/* Not libGL, so just return real dlopen */
if (STRNCMP_LITERAL (filename, "libGL.so"))
- return dlwrap_real_dlopen (filename, flag);
+ return ret;
- /* Redirect all dlopens to libGL to our own wrapper library.
- * We find our own filename by looking up this very function
- * (that is, this "dlopen"), with dladdr).*/
- if (dladdr (dlopen, &info)) {
- libfips_handle = dlwrap_real_dlopen (info.dli_fname, flag);
+ /* Otherwise, for all libGL lookups we redirectl dlopens to
+ * our own library. If we've resolved libfips_handle before,
+ * our work is done. */
+ if (libfips_handle)
return libfips_handle;
- } else {
+
+ /* We find our own filename by looking up this very function
+ * (that is, this "dlopen"), with dladdr).*/
+ if (dladdr (dlopen, &info) == 0) {
fprintf (stderr, "Error: Failed to redirect dlopen of %s:\n",
filename);
exit (1);
}
+
+ libfips_handle = dlwrap_real_dlopen (info.dli_fname, flag);
+
+ return libfips_handle;
}
void *
dlwrap_real_dlopen (const char *filename, int flag)
{
- fips_dlopen_t real_dlopen = NULL;
+ static fips_dlopen_t real_dlopen = NULL;
if (! real_dlopen) {
real_dlopen = (fips_dlopen_t) dlwrap_real_dlsym (RTLD_NEXT, "dlopen");