Files
nt-lite/code/user/tests/posix_module_smoke/posix_module_smoke.c
T

66 lines
1.9 KiB
C

// User-mode smoke test for POSIX dynamic module loading.
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#define RTLD_NOW 0x0002
#define RTLD_LOCAL 0x0004
typedef int64_t ssize_t;
extern ssize_t write(int fd, const void* buf, size_t count);
extern void exit(int status);
extern void* dlopen(const char* filename, int flags);
extern void* dlsym(void* handle, const char* symbol);
extern int dlclose(void* handle);
extern char* dlerror(void);
// Writes one NUL-terminated string to stdout.
static void print(const char* s) {
write(1, s, strlen(s));
}
// Terminates the current process.
static void exit_now(int code) {
for (;;) exit(code);
}
// Fails the smoke test with one message.
static void fail(const char* message) {
print("posix_module_smoke: ");
print(message);
print("\n");
exit_now(1);
}
// Verifies that dlerror reports and clears one loader error.
static void check_dlerror_clear(void) {
void* missing = dlsym(0, "definitely_missing");
if (missing) fail("dlsym unexpectedly succeeded");
char* first = dlerror();
if (!first || !first[0]) fail("dlerror did not report the failure");
char* second = dlerror();
if (second) fail("dlerror did not clear the failure");
}
// Runs the POSIX dynamic loader smoke test.
int main(void) {
print("posix_module_smoke: start\n");
check_dlerror_clear();
void* module = dlopen("syscall.dll", RTLD_NOW | RTLD_LOCAL);
if (!module) fail("dlopen syscall.dll failed");
typedef uint32_t (__stdcall *GETPID_FN)(void);
GETPID_FN getpid_native = (GETPID_FN)dlsym(module, "SysGetCurrentPid");
if (!getpid_native) fail("dlsym SysGetCurrentPid failed");
if (getpid_native() == 0) fail("resolved SysGetCurrentPid returned zero");
if (dlclose(module) != 0) fail("dlclose syscall.dll failed");
print("posix_module_smoke: PASS\n");
exit_now(0);
return 0;
}