unit-tests: Uninline dlopen() and friends, make more dynamic, fix dlerror()
authorMartin Willi <martin@revosec.ch>
Fri, 25 Oct 2013 14:03:07 +0000 (16:03 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Jun 2014 13:53:02 +0000 (15:53 +0200)
As the error string contains a newline, we have to remove that before
returning the string.

src/libstrongswan/utils/windows.c
src/libstrongswan/utils/windows.h

index 4a6a35e..feefcd4 100644 (file)
@@ -49,6 +49,130 @@ int usleep(useconds_t usec)
        return 0;
 }
 
        return 0;
 }
 
+/*
+ * See header.
+ */
+void *dlopen(const char *filename, int flag)
+{
+       return LoadLibrary(filename);
+}
+
+/**
+ * Load a symbol from known default libs (monolithic build)
+ */
+static void* dlsym_default(const char *name)
+{
+       const char *dlls[] = {
+               "libstrongswan-0.dll",
+               "libhydra-0.dll",
+               "libcharon-0.dll",
+               "libtnccs-0.dll",
+               NULL /* .exe */
+       };
+       HANDLE handle;
+       void *sym = NULL;
+       int i;
+
+       for (i = 0; i < countof(dlls); i++)
+       {
+               handle = GetModuleHandle(dlls[i]);
+               if (handle)
+               {
+                       sym = GetProcAddress(handle, name);
+                       if (sym)
+                       {
+                               break;
+                       }
+               }
+       }
+       return sym;
+}
+
+/**
+ * Emulate RTLD_NEXT for some known symbols
+ */
+static void* dlsym_next(const char *name)
+{
+       struct {
+               const char *dll;
+               const char *syms[4];
+       } dlls[] = {
+               /* for leak detective */
+               { "msvcrt",
+                       { "malloc", "calloc", "realloc", "free" }
+               },
+       };
+       HANDLE handle = NULL;
+       int i, j;
+
+       for (i = 0; i < countof(dlls); i++)
+       {
+               for (j = 0; j < countof(dlls[0].syms); j++)
+               {
+                       if (dlls[i].syms[j] && streq(dlls[i].syms[j], name))
+                       {
+                               handle = GetModuleHandle(dlls[i].dll);
+                               break;
+                       }
+               }
+       }
+       if (handle)
+       {
+               return GetProcAddress(handle, name);
+       }
+       return handle;
+}
+
+/**
+ * See header.
+ */
+void* dlsym(void *handle, const char *symbol)
+{
+       if (handle == RTLD_DEFAULT)
+       {
+               return dlsym_default(symbol);
+       }
+       if (handle == RTLD_NEXT)
+       {
+               return dlsym_next(symbol);
+       }
+       return GetProcAddress((HMODULE)handle, symbol);
+}
+
+/**
+ * See header.
+ */
+char* dlerror(void)
+{
+       static char buf[128];
+       char *pos;
+       DWORD err;
+
+       err = GetLastError();
+       if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                                         NULL, err, 0, buf, sizeof(buf), NULL) > 0)
+       {
+               pos = strchr(buf, '\n');
+               if (pos)
+               {
+                       *pos = '\0';
+               }
+       }
+       else
+       {
+               snprintf(buf, sizeof(buf), "(%u)", err);
+       }
+       return buf;
+}
+
+/**
+ * See header.
+ */
+int dlclose(void *handle)
+{
+       return FreeLibrary((HMODULE)handle);
+}
+
 /**
  * See header
  */
 /**
  * See header
  */
index 8e6fd80..e070a79 100644 (file)
@@ -204,39 +204,11 @@ static inline int setenv(const char *name, const char *value, int overwrite)
 }
 
 /**
 }
 
 /**
- * dlerror(3) from <dlfcn.h>, printing error to an alloca() buffer
- */
-#define dlerror() \
-({ \
-       char buf[128], *out;\
-       ssize_t len; \
-       DWORD err; \
-       err = GetLastError(); \
-       len = FormatMessage(0, NULL, err, 0, buf, sizeof(buf), NULL); \
-       if (len <= 0) \
-       { \
-               len = snprintf(buf, sizeof(buf), "(%u)", err); \
-       } \
-       len++; \
-       out = alloca(len); \
-       memcpy(out, buf, len); \
-       out; \
-})
-
-/**
  * Lazy binding, ignored on Windows
  */
 #define RTLD_LAZY 1
 
 /**
  * Lazy binding, ignored on Windows
  */
 #define RTLD_LAZY 1
 
 /**
- * dlopen(3) from <dlfcn.h>
- */
-static inline void *dlopen(const char *filename, int flag)
-{
-       return LoadLibrary(filename);
-}
-
-/**
  * Default handle targeting .exe
  */
 #define RTLD_DEFAULT (NULL)
  * Default handle targeting .exe
  */
 #define RTLD_DEFAULT (NULL)
@@ -247,42 +219,24 @@ static inline void *dlopen(const char *filename, int flag)
 #define RTLD_NEXT ((void*)~(uintptr_t)0)
 
 /**
 #define RTLD_NEXT ((void*)~(uintptr_t)0)
 
 /**
+ * dlopen(3) from <dlfcn.h>
+ */
+void* dlopen(const char *filename, int flag);
+
+/**
  * dlsym() from <dlfcn.h>
  */
  * dlsym() from <dlfcn.h>
  */
-static inline void *dlsym(void *handle, const char *symbol)
-{
-       if (handle == RTLD_DEFAULT)
-       {
-               handle = GetModuleHandle(NULL);
-       }
-       else if (handle == RTLD_NEXT)
-       {
-               if (strcmp(symbol, "malloc") == 0 ||
-                       strcmp(symbol, "realloc") == 0 ||
-                       strcmp(symbol, "free") == 0)
-               {
-                       /* for leak-detective */
-                       handle = GetModuleHandle("msvcrt");
-               }
-               else
-               {
-                       return NULL;
-               }
-       }
-       if (handle)
-       {
-               return GetProcAddress((HMODULE)handle, symbol);
-       }
-       return NULL;
-}
+void* dlsym(void *handle, const char *symbol);
+
+/**
+ * dlerror(3) from <dlfcn.h>, currently not thread save
+ */
+char* dlerror(void);
 
 /**
  * dlclose() from <dlfcn.h>
  */
 
 /**
  * dlclose() from <dlfcn.h>
  */
-static inline int dlclose(void *handle)
-{
-       return FreeLibrary((HMODULE)handle);
-}
+int dlclose(void *handle);
 
 /**
  * socketpair(2) for SOCK_STREAM, uses TCP on loopback
 
 /**
  * socketpair(2) for SOCK_STREAM, uses TCP on loopback