Commit | Line | Data |
---|---|---|
cf736a07 RB |
1 | /* ltdl.h -- generic dlopen functions |
2 | Copyright (C) 1998-2000, 2002 Free Software Foundation, Inc. | |
3 | Originally by Thomas Tanner <tanner@ffii.org> | |
4 | This file is part of GNU Libtool. | |
5 | ||
6 | This library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2 of the License, or (at your option) any later version. | |
10 | ||
11 | As a special exception to the GNU Lesser General Public License, | |
12 | if you distribute this file as part of a program or library that | |
13 | is built using GNU libtool, you may include it under the same | |
14 | distribution terms that you use for the rest of that program. | |
15 | ||
16 | This library is distributed in the hope that it will be useful, | |
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 | Lesser General Public License for more details. | |
20 | ||
21 | You should have received a copy of the GNU Lesser General Public | |
22 | License along with this library; if not, write to the Free | |
92205699 MV |
23 | Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
24 | 02110-1301 USA | |
cf736a07 RB |
25 | */ |
26 | ||
27 | /* Only include this header file once. */ | |
28 | #ifndef LTDL_H | |
29 | #define LTDL_H 1 | |
30 | ||
31 | #include "guile-ltdl.h" | |
32 | ||
33 | #include <sys/types.h> /* for size_t declaration */ | |
34 | ||
35 | \f | |
36 | /* --- MACROS FOR PORTABILITY --- */ | |
37 | ||
38 | /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, | |
39 | so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at | |
40 | the end of C declarations. */ | |
41 | #ifdef __cplusplus | |
42 | # define LT_BEGIN_C_DECLS extern "C" { | |
43 | # define LT_END_C_DECLS } | |
44 | #else | |
45 | # define LT_BEGIN_C_DECLS /* empty */ | |
46 | # define LT_END_C_DECLS /* empty */ | |
47 | #endif | |
48 | ||
49 | LT_BEGIN_C_DECLS | |
50 | ||
51 | ||
52 | /* LT_PARAMS is a macro used to wrap function prototypes, so that compilers | |
53 | that don't understand ANSI C prototypes still work, and ANSI C | |
54 | compilers can issue warnings about type mismatches. */ | |
55 | #if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus) | |
56 | # define LT_PARAMS(protos) protos | |
57 | # define lt_ptr void* | |
58 | #else | |
59 | # define LT_PARAMS(protos) () | |
60 | # define lt_ptr char* | |
61 | #endif | |
62 | ||
63 | /* LT_STMT_START/END are used to create macros which expand to a | |
64 | a single compound statement in a portable way. */ | |
65 | #if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) | |
66 | # define LT_STMT_START (void)( | |
67 | # define LT_STMT_END ) | |
68 | #else | |
69 | # if (defined (sun) || defined (__sun__)) | |
70 | # define LT_STMT_START if (1) | |
71 | # define LT_STMT_END else (void)0 | |
72 | # else | |
73 | # define LT_STMT_START do | |
74 | # define LT_STMT_END while (0) | |
75 | # endif | |
76 | #endif | |
77 | ||
78 | /* LT_CONC creates a new concatenated symbol for the compiler | |
79 | in a portable way. */ | |
80 | #if defined(__STDC__) || defined(__cplusplus) | |
81 | # define LT_CONC(s,t) s##t | |
82 | #else | |
83 | # define LT_CONC(s,t) s/**/t | |
84 | #endif | |
85 | ||
86 | /* LT_STRLEN can be used safely on NULL pointers. */ | |
87 | #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) | |
88 | ||
89 | ||
90 | \f | |
91 | /* --- WINDOWS SUPPORT --- */ | |
92 | ||
93 | ||
94 | /* Canonicalise Windows and Cygwin recognition macros. */ | |
95 | #ifdef __CYGWIN32__ | |
96 | # ifndef __CYGWIN__ | |
97 | # define __CYGWIN__ __CYGWIN32__ | |
98 | # endif | |
99 | #endif | |
100 | #if defined(_WIN32) || defined(WIN32) | |
101 | # ifndef __WINDOWS__ | |
102 | # ifdef _WIN32 | |
103 | # define __WINDOWS__ _WIN32 | |
104 | # else | |
105 | # ifdef WIN32 | |
106 | # define __WINDOWS__ WIN32 | |
107 | # endif | |
108 | # endif | |
109 | # endif | |
110 | #endif | |
111 | ||
112 | #ifdef __WINDOWS__ | |
113 | # ifndef __CYGWIN__ | |
114 | /* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory | |
115 | separator when it is set. */ | |
116 | # define LT_DIRSEP_CHAR '\\' | |
117 | # define LT_PATHSEP_CHAR ';' | |
118 | # endif | |
119 | #endif | |
120 | #ifndef LT_PATHSEP_CHAR | |
121 | # define LT_PATHSEP_CHAR ':' | |
122 | #endif | |
123 | ||
124 | /* DLL building support on win32 hosts; mostly to workaround their | |
125 | ridiculous implementation of data symbol exporting. */ | |
126 | #ifndef LT_SCOPE | |
127 | # ifdef __WINDOWS__ | |
128 | # ifdef DLL_EXPORT /* defined by libtool (if required) */ | |
129 | # define LT_SCOPE __declspec(dllexport) | |
130 | # endif | |
131 | # ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */ | |
132 | # define LT_SCOPE extern __declspec(dllimport) | |
133 | # endif | |
134 | # endif | |
135 | # ifndef LT_SCOPE /* static linking or !__WINDOWS__ */ | |
136 | # define LT_SCOPE extern | |
137 | # endif | |
138 | #endif | |
139 | ||
140 | ||
141 | ||
142 | \f | |
143 | /* --- DYNAMIC MODULE LOADING API --- */ | |
144 | ||
145 | ||
146 | typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */ | |
147 | ||
148 | /* Initialisation and finalisation functions for libltdl. */ | |
149 | SCMLTXT int lt_dlinit LT_PARAMS((void)); | |
150 | SCMLTXT int lt_dlexit LT_PARAMS((void)) SCM_UNUSED; | |
151 | ||
152 | /* Module search path manipulation. */ | |
153 | SCMLTXT int lt_dladdsearchdir LT_PARAMS((const char *search_dir)) SCM_UNUSED; | |
154 | SCMLTXT int lt_dlinsertsearchdir LT_PARAMS((const char *before, | |
155 | const char *search_dir)) SCM_UNUSED; | |
156 | SCMLTXT int lt_dlsetsearchpath LT_PARAMS((const char *search_path)) SCM_UNUSED; | |
157 | SCMLTXT const char *lt_dlgetsearchpath LT_PARAMS((void)) SCM_UNUSED; | |
158 | SCMLTXT int lt_dlforeachfile LT_PARAMS(( | |
159 | const char *search_path, | |
160 | int (*func) (const char *filename, lt_ptr data), | |
161 | lt_ptr data)) SCM_UNUSED; | |
162 | ||
163 | /* Portable libltdl versions of the system dlopen() API. */ | |
164 | SCMLTXT lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); | |
165 | SCMLTXT lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); | |
166 | SCMLTXT lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, | |
167 | const char *name)); | |
168 | SCMLTXT const char *lt_dlerror LT_PARAMS((void)); | |
169 | SCMLTXT int lt_dlclose LT_PARAMS((lt_dlhandle handle)); | |
170 | ||
171 | /* Module residency management. */ | |
172 | SCMLTXT int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)) SCM_UNUSED; | |
173 | SCMLTXT int lt_dlisresident LT_PARAMS((lt_dlhandle handle)) SCM_UNUSED; | |
174 | ||
175 | ||
176 | ||
177 | \f | |
178 | /* --- MUTEX LOCKING --- */ | |
179 | ||
180 | ||
181 | typedef void lt_dlmutex_lock LT_PARAMS((void)); | |
182 | typedef void lt_dlmutex_unlock LT_PARAMS((void)); | |
183 | typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); | |
184 | typedef const char *lt_dlmutex_geterror LT_PARAMS((void)); | |
185 | ||
186 | SCMLTXT int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, | |
187 | lt_dlmutex_unlock *unlock, | |
188 | lt_dlmutex_seterror *seterror, | |
189 | lt_dlmutex_geterror *geterror)) SCM_UNUSED; | |
190 | ||
191 | ||
192 | ||
193 | \f | |
194 | /* --- MEMORY HANDLING --- */ | |
195 | ||
196 | ||
197 | /* By default, the realloc function pointer is set to our internal | |
198 | realloc implementation which iself uses lt_dlmalloc and lt_dlfree. | |
199 | libltdl relies on a featureful realloc, but if you are sure yours | |
200 | has the right semantics then you can assign it directly. Generally, | |
201 | it is safe to assign just a malloc() and a free() function. */ | |
202 | LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)); | |
203 | LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) SCM_UNUSED; | |
204 | LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)); | |
205 | ||
206 | ||
207 | ||
208 | \f | |
209 | /* --- PRELOADED MODULE SUPPORT --- */ | |
210 | ||
211 | ||
212 | /* A preopened symbol. Arrays of this type comprise the exported | |
213 | symbols for a dlpreopened module. */ | |
c11a6400 | 214 | typedef struct SCM_INSERTED_DLSYMLIST_STRUCT_DECL { |
cf736a07 RB |
215 | const char *name; |
216 | lt_ptr address; | |
217 | } lt_dlsymlist; | |
218 | ||
219 | SCMLTXT int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); | |
220 | SCMLTXT int lt_dlpreload_default | |
221 | LT_PARAMS((const lt_dlsymlist *preloaded)); | |
222 | ||
223 | #define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ | |
224 | extern const lt_dlsymlist lt_preloaded_symbols[]; \ | |
225 | lt_dlpreload_default(lt_preloaded_symbols); \ | |
226 | }LT_STMT_END | |
227 | ||
228 | ||
229 | ||
230 | \f | |
231 | /* --- MODULE INFORMATION --- */ | |
232 | ||
233 | ||
234 | /* Read only information pertaining to a loaded module. */ | |
235 | typedef struct { | |
236 | char *filename; /* file name */ | |
237 | char *name; /* module name */ | |
238 | int ref_count; /* number of times lt_dlopened minus | |
239 | number of times lt_dlclosed. */ | |
240 | } lt_dlinfo; | |
241 | ||
242 | SCMLTXT const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)) SCM_UNUSED; | |
243 | SCMLTXT lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)) SCM_UNUSED; | |
244 | SCMLTXT int lt_dlforeach LT_PARAMS(( | |
245 | int (*func) (lt_dlhandle handle, lt_ptr data), | |
246 | lt_ptr data)) SCM_UNUSED; | |
247 | ||
248 | /* Associating user data with loaded modules. */ | |
249 | typedef unsigned lt_dlcaller_id; | |
250 | ||
251 | SCMLTXT lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)) SCM_UNUSED; | |
252 | SCMLTXT lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, | |
253 | lt_dlhandle handle, | |
254 | lt_ptr data)) SCM_UNUSED; | |
255 | SCMLTXT lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, | |
256 | lt_dlhandle handle)) SCM_UNUSED; | |
257 | ||
258 | ||
259 | \f | |
260 | /* --- USER MODULE LOADER API --- */ | |
261 | ||
262 | ||
263 | typedef struct lt_dlloader lt_dlloader; | |
264 | typedef lt_ptr lt_user_data; | |
265 | typedef lt_ptr lt_module; | |
266 | ||
267 | /* Function pointer types for creating user defined module loaders. */ | |
268 | typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data, | |
269 | const char *filename)); | |
270 | typedef int lt_module_close LT_PARAMS((lt_user_data loader_data, | |
271 | lt_module handle)); | |
272 | typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data, | |
273 | lt_module handle, | |
274 | const char *symbol)); | |
275 | typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data)); | |
276 | ||
277 | struct lt_user_dlloader { | |
278 | const char *sym_prefix; | |
279 | lt_module_open *module_open; | |
280 | lt_module_close *module_close; | |
281 | lt_find_sym *find_sym; | |
282 | lt_dlloader_exit *dlloader_exit; | |
283 | lt_user_data dlloader_data; | |
284 | }; | |
285 | ||
286 | SCMLTXT lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); | |
287 | SCMLTXT lt_dlloader *lt_dlloader_find LT_PARAMS(( | |
288 | const char *loader_name)); | |
289 | SCMLTXT const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)) SCM_UNUSED; | |
290 | SCMLTXT lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)) SCM_UNUSED; | |
291 | SCMLTXT int lt_dlloader_add LT_PARAMS((lt_dlloader *place, | |
292 | const struct lt_user_dlloader *dlloader, | |
293 | const char *loader_name)); | |
294 | SCMLTXT int lt_dlloader_remove LT_PARAMS(( | |
295 | const char *loader_name)) SCM_UNUSED; | |
296 | ||
297 | ||
298 | \f | |
299 | /* --- ERROR MESSAGE HANDLING --- */ | |
300 | ||
301 | ||
302 | /* Defining error strings alongside their symbolic names in a macro in | |
303 | this way allows us to expand the macro in different contexts with | |
304 | confidence that the enumeration of symbolic names will map correctly | |
305 | onto the table of error strings. */ | |
306 | #define lt_dlerror_table \ | |
307 | LT_ERROR(UNKNOWN, "unknown error") \ | |
308 | LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \ | |
309 | LT_ERROR(INVALID_LOADER, "invalid loader") \ | |
310 | LT_ERROR(INIT_LOADER, "loader initialization failed") \ | |
311 | LT_ERROR(REMOVE_LOADER, "loader removal failed") \ | |
312 | LT_ERROR(FILE_NOT_FOUND, "file not found") \ | |
313 | LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \ | |
314 | LT_ERROR(NO_SYMBOLS, "no symbols defined") \ | |
315 | LT_ERROR(CANNOT_OPEN, "can't open the module") \ | |
316 | LT_ERROR(CANNOT_CLOSE, "can't close the module") \ | |
317 | LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \ | |
318 | LT_ERROR(NO_MEMORY, "not enough memory") \ | |
319 | LT_ERROR(INVALID_HANDLE, "invalid module handle") \ | |
320 | LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \ | |
321 | LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ | |
322 | LT_ERROR(SHUTDOWN, "library already shutdown") \ | |
323 | LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ | |
324 | LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ | |
325 | LT_ERROR(INVALID_POSITION, "invalid search path insert position") | |
326 | ||
327 | /* Enumerate the symbolic error names. */ | |
328 | enum { | |
329 | #define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), | |
330 | lt_dlerror_table | |
331 | #undef LT_ERROR | |
332 | ||
333 | LT_ERROR_MAX | |
334 | }; | |
335 | ||
336 | /* These functions are only useful from inside custom module loaders. */ | |
337 | SCMLTXT int lt_dladderror LT_PARAMS((const char *diagnostic)) SCM_UNUSED; | |
338 | SCMLTXT int lt_dlseterror LT_PARAMS((int errorcode)) SCM_UNUSED; | |
339 | ||
340 | ||
341 | ||
342 | LT_END_C_DECLS | |
343 | ||
344 | #endif /* !LTDL_H */ |