]> git.proxmox.com Git - wasi-libc.git/blob - libc-top-half/musl/src/ldso/dlerror.c
WASI libc prototype implementation.
[wasi-libc.git] / libc-top-half / musl / src / ldso / dlerror.c
1 #include <dlfcn.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include "pthread_impl.h"
5 #include "dynlink.h"
6
7 char *dlerror()
8 {
9 pthread_t self = __pthread_self();
10 if (!self->dlerror_flag) return 0;
11 self->dlerror_flag = 0;
12 char *s = self->dlerror_buf;
13 if (s == (void *)-1)
14 return "Dynamic linker failed to allocate memory for error message";
15 else
16 return s;
17 }
18
19 void __dl_thread_cleanup(void)
20 {
21 pthread_t self = __pthread_self();
22 if (self->dlerror_buf != (void *)-1)
23 free(self->dlerror_buf);
24 }
25
26 hidden void __dl_vseterr(const char *fmt, va_list ap)
27 {
28 va_list ap2;
29 va_copy(ap2, ap);
30 pthread_t self = __pthread_self();
31 if (self->dlerror_buf != (void *)-1)
32 free(self->dlerror_buf);
33 size_t len = vsnprintf(0, 0, fmt, ap2);
34 va_end(ap2);
35 char *buf = malloc(len+1);
36 if (buf) {
37 vsnprintf(buf, len+1, fmt, ap);
38 } else {
39 buf = (void *)-1;
40 }
41 self->dlerror_buf = buf;
42 self->dlerror_flag = 1;
43 }
44
45 hidden void __dl_seterr(const char *fmt, ...)
46 {
47 va_list ap;
48 va_start(ap, fmt);
49 __dl_vseterr(fmt, ap);
50 va_end(ap);
51 }
52
53 static int stub_invalid_handle(void *h)
54 {
55 __dl_seterr("Invalid library handle %p", (void *)h);
56 return 1;
57 }
58
59 weak_alias(stub_invalid_handle, __dl_invalid_handle);