unit-tests: Uninline dlopen() and friends, make more dynamic, fix dlerror()

As the error string contains a newline, we have to remove that before
returning the string.
This commit is contained in:
Martin Willi 2013-10-25 16:03:07 +02:00
parent 204098a752
commit 110e42361e
2 changed files with 136 additions and 58 deletions

View File

@ -49,6 +49,130 @@ int usleep(useconds_t usec)
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
*/

View File

@ -203,39 +203,11 @@ static inline int setenv(const char *name, const char *value, int overwrite)
return 0;
}
/**
* 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
/**
* dlopen(3) from <dlfcn.h>
*/
static inline void *dlopen(const char *filename, int flag)
{
return LoadLibrary(filename);
}
/**
* Default handle targeting .exe
*/
@ -246,43 +218,25 @@ static inline void *dlopen(const char *filename, int flag)
*/
#define RTLD_NEXT ((void*)~(uintptr_t)0)
/**
* dlopen(3) from <dlfcn.h>
*/
void* dlopen(const char *filename, int flag);
/**
* 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>
*/
static inline int dlclose(void *handle)
{
return FreeLibrary((HMODULE)handle);
}
int dlclose(void *handle);
/**
* socketpair(2) for SOCK_STREAM, uses TCP on loopback