moved back to old acc
[vox.git] / src / stdlib / sharedlib.c
blob84974e476f72b63d489ac50e1464f7d5d5e6878c
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "sharedlib.h"
7 #if defined(SHAREDLIB_ISWINNT)
8 # include <windows.h>
9 #elif defined(SHAREDLIB_ISUNIX)
10 # include <unistd.h>
11 # include <dlfcn.h>
12 # include <errno.h>
13 #endif
15 struct shl_handle_t {
16 #ifdef SHAREDLIB_ISWINNT
17 /* technically, HANDLE is just typedef'd to 'const void*' anyway */
18 HANDLE libhandle;
19 #elif defined(SHAREDLIB_ISUNIX)
20 void* libhandle;
21 #endif
22 /* currently not really used */
23 int isloaded;
26 shl_handle_t* shl_new()
28 shl_handle_t* ret;
29 ret = (shl_handle_t*)malloc(sizeof(shl_handle_t));
30 ret->libhandle = NULL;
31 ret->isloaded = 0;
32 return ret;
35 shl_handle_t* shl_openlib(const char* path)
37 shl_handle_t* ret;
38 ret = shl_new();
39 #if defined(SHAREDLIB_ISWINNT)
40 ret->libhandle = LoadLibrary(path);
41 #elif defined(SHAREDLIB_ISUNIX)
42 ret->libhandle = dlopen(path, RTLD_LAZY);
43 #endif
44 if(ret->libhandle == NULL)
46 shl_destroy(ret);
47 return NULL;
49 return ret;
52 shl_handle_t* shl_openself()
54 shl_handle_t* ret;
55 ret = shl_new();
56 #if defined(SHAREDLIB_ISWINNT)
57 HANDLE this_process;
58 /* GetModuleHandleEx(0,0, &this_process); */
59 this_process = GetModuleHandle(0);
60 ret->libhandle = this_process;
61 #elif defined(SHAREDLIB_ISUNIX)
62 ret->libhandle = dlopen(NULL, 0);
63 #endif
64 return ret;
68 void shl_destroy(shl_handle_t* shl)
70 if(shl != NULL)
72 free(shl);
73 shl = NULL;
77 void shl_closelib(shl_handle_t* shl)
79 if(shl != NULL)
81 #if defined(SHAREDLIB_ISWINNT)
82 FreeLibrary(shl->libhandle);
83 #elif defined(SHAREDLIB_ISUNIX)
84 dlclose(shl->libhandle);
85 #endif
87 shl_destroy(shl);
90 int shl_havesym(shl_handle_t* shl, const char* sym)
92 if(shl_resolve(shl, sym) == NULL)
94 return 0;
96 return 1;
99 void* shl_resolve(shl_handle_t* shl, const char* sym)
101 void* symaddr;
102 #if defined(SHAREDLIB_ISWINNT)
103 symaddr = (void*)GetProcAddress(shl->libhandle, sym);
104 #elif defined(SHAREDLIB_ISUNIX)
105 symaddr = (void*)dlsym(shl->libhandle, sym);
106 #endif
107 return symaddr;
110 void* shl_loadsym(shl_handle_t* shl, const char* sym)
112 if(shl_havesym(shl, sym) == 0)
114 return NULL;
116 return shl_resolve(shl, sym);
119 int shl_geterrcode(shl_handle_t* shl)
121 (void)shl;
122 #if defined(SHAREDLIB_ISWINNT)
123 /* the interface for loading/unloading shared objects on
124 windows uses the global errorcode system */
125 return GetLastError();
126 #elif defined(SHAREDLIB_ISUNIX)
127 return errno;
128 #endif
131 const char* shl_geterrstr(shl_handle_t* shl)
133 #if defined(SHAREDLIB_ISWINNT)
134 int errval = shl_geterrcode(shl);
136 sometimes, in localized versions of Windows XP (and newer),
137 the output returned by FormatMessage() contains "\r\n" ...
138 so far I have not found a 'sane' way to fix this.
139 also, it's not like i'm the one who should fix this in the first place.
140 YES MICROSOFT I AM TALKING ABOUT YOU FIX YOUR SHIT FOR FUCKS SAKE
142 LPCSTR tempmessage;
143 FormatMessage(
144 FORMAT_MESSAGE_FROM_SYSTEM |
145 FORMAT_MESSAGE_ALLOCATE_BUFFER |
146 FORMAT_MESSAGE_IGNORE_INSERTS,
147 NULL, errval, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
148 (LPTSTR)& tempmessage, 0,NULL);
149 return tempmessage;
150 #elif defined(SHAREDLIB_ISUNIX)
151 const char* errstr;
152 /* sometimes dlerror() returns NULL, and in that case,
153 we just use strerror() instead */
154 if((errstr = dlerror()) == NULL)
156 errstr = strerror(shl_geterrcode(shl));
158 return errstr;
159 #endif
162 int shl_preload(const char* path)
164 shl_handle_t* handle;
165 if((handle = shl_openlib(path)) == NULL)
167 return 0;
169 shl_closelib(handle);
170 return 1;