ยปCore Development>Code coverage>Modules/_ctypes/darwin/dlfcn_simple.c

Python code coverage for Modules/_ctypes/darwin/dlfcn_simple.c

#countcontent
1n/a/*
2n/aCopyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
3n/a
4n/aPermission is hereby granted, free of charge, to any person obtaining
5n/aa copy of this software and associated documentation files (the
6n/a"Software"), to deal in the Software without restriction, including
7n/awithout limitation the rights to use, copy, modify, merge, publish,
8n/adistribute, sublicense, and/or sell copies of the Software, and to
9n/apermit persons to whom the Software is furnished to do so, subject to
10n/athe following conditions:
11n/a
12n/aThe above copyright notice and this permission notice shall be
13n/aincluded in all copies or substantial portions of the Software.
14n/a
15n/aTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16n/aEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17n/aMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18n/aNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19n/aLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20n/aOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21n/aWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22n/a*/
23n/a
24n/a
25n/a/* Just to prove that it isn't that hard to add Mac calls to your code :)
26n/a This works with pretty much everything, including kde3 xemacs and the gimp,
27n/a I'd guess that it'd work in at least 95% of cases, use this as your starting
28n/a point, rather than the mess that is dlfcn.c, assuming that your code does not
29n/a require ref counting or symbol lookups in dependent libraries
30n/a*/
31n/a
32n/a#include <stdio.h>
33n/a#include <stdlib.h>
34n/a#include <string.h>
35n/a#include <sys/types.h>
36n/a#include <sys/stat.h>
37n/a#include <stdarg.h>
38n/a#include <limits.h>
39n/a#include <mach-o/dyld.h>
40n/a#include <AvailabilityMacros.h>
41n/a#include "dlfcn.h"
42n/a
43n/a#ifdef CTYPES_DARWIN_DLFCN
44n/a
45n/a#define ERR_STR_LEN 256
46n/a
47n/a#ifndef MAC_OS_X_VERSION_10_3
48n/a#define MAC_OS_X_VERSION_10_3 1030
49n/a#endif
50n/a
51n/a#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
52n/a#define DARWIN_HAS_DLOPEN
53n/aextern void * dlopen(const char *path, int mode) __attribute__((weak_import));
54n/aextern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
55n/aextern const char * dlerror(void) __attribute__((weak_import));
56n/aextern int dlclose(void * handle) __attribute__((weak_import));
57n/aextern int dladdr(const void *, Dl_info *) __attribute__((weak_import));
58n/a#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
59n/a
60n/a#ifndef DARWIN_HAS_DLOPEN
61n/a#define dlopen darwin_dlopen
62n/a#define dlsym darwin_dlsym
63n/a#define dlerror darwin_dlerror
64n/a#define dlclose darwin_dlclose
65n/a#define dladdr darwin_dladdr
66n/a#endif
67n/a
68n/avoid * (*ctypes_dlopen)(const char *path, int mode);
69n/avoid * (*ctypes_dlsym)(void * handle, const char *symbol);
70n/aconst char * (*ctypes_dlerror)(void);
71n/aint (*ctypes_dlclose)(void * handle);
72n/aint (*ctypes_dladdr)(const void *, Dl_info *);
73n/a
74n/a#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
75n/a/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */
76n/a
77n/astatic void *dlsymIntern(void *handle, const char *symbol);
78n/a
79n/astatic const char *error(int setget, const char *str, ...);
80n/a
81n/a/* Set and get the error string for use by dlerror */
82n/astatic const char *error(int setget, const char *str, ...)
83n/a{
84n/a static char errstr[ERR_STR_LEN];
85n/a static int err_filled = 0;
86n/a const char *retval;
87n/a va_list arg;
88n/a if (setget == 0)
89n/a {
90n/a va_start(arg, str);
91n/a strncpy(errstr, "dlcompat: ", ERR_STR_LEN);
92n/a vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
93n/a va_end(arg);
94n/a err_filled = 1;
95n/a retval = NULL;
96n/a }
97n/a else
98n/a {
99n/a if (!err_filled)
100n/a retval = NULL;
101n/a else
102n/a retval = errstr;
103n/a err_filled = 0;
104n/a }
105n/a return retval;
106n/a}
107n/a
108n/a/* darwin_dlopen */
109n/astatic void *darwin_dlopen(const char *path, int mode)
110n/a{
111n/a void *module = 0;
112n/a NSObjectFileImage ofi = 0;
113n/a NSObjectFileImageReturnCode ofirc;
114n/a
115n/a /* If we got no path, the app wants the global namespace, use -1 as the marker
116n/a in this case */
117n/a if (!path)
118n/a return (void *)-1;
119n/a
120n/a /* Create the object file image, works for things linked with the -bundle arg to ld */
121n/a ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
122n/a switch (ofirc)
123n/a {
124n/a case NSObjectFileImageSuccess:
125n/a /* It was okay, so use NSLinkModule to link in the image */
126n/a module = NSLinkModule(ofi, path,
127n/a NSLINKMODULE_OPTION_RETURN_ON_ERROR
128n/a | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE
129n/a | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
130n/a NSDestroyObjectFileImage(ofi);
131n/a break;
132n/a case NSObjectFileImageInappropriateFile:
133n/a /* It may have been a dynamic library rather than a bundle, try to load it */
134n/a module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
135n/a break;
136n/a default:
137n/a /* God knows what we got */
138n/a error(0, "Can not open \"%s\"", path);
139n/a return 0;
140n/a }
141n/a if (!module)
142n/a error(0, "Can not open \"%s\"", path);
143n/a return module;
144n/a
145n/a}
146n/a
147n/a/* dlsymIntern is used by dlsym to find the symbol */
148n/astatic void *dlsymIntern(void *handle, const char *symbol)
149n/a{
150n/a NSSymbol nssym = 0;
151n/a /* If the handle is -1, if is the app global context */
152n/a if (handle == (void *)-1)
153n/a {
154n/a /* Global context, use NSLookupAndBindSymbol */
155n/a if (NSIsSymbolNameDefined(symbol))
156n/a {
157n/a nssym = NSLookupAndBindSymbol(symbol);
158n/a }
159n/a
160n/a }
161n/a /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image
162n/a for libraries, and NSLookupSymbolInModule for bundles */
163n/a else
164n/a {
165n/a /* Check for both possible magic numbers depending on x86/ppc byte order */
166n/a if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
167n/a (((struct mach_header *)handle)->magic == MH_CIGAM))
168n/a {
169n/a if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol))
170n/a {
171n/a nssym = NSLookupSymbolInImage((struct mach_header *)handle,
172n/a symbol,
173n/a NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
174n/a | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
175n/a }
176n/a
177n/a }
178n/a else
179n/a {
180n/a nssym = NSLookupSymbolInModule(handle, symbol);
181n/a }
182n/a }
183n/a if (!nssym)
184n/a {
185n/a error(0, "Symbol \"%s\" Not found", symbol);
186n/a return NULL;
187n/a }
188n/a return NSAddressOfSymbol(nssym);
189n/a}
190n/a
191n/astatic const char *darwin_dlerror(void)
192n/a{
193n/a return error(1, (char *)NULL);
194n/a}
195n/a
196n/astatic int darwin_dlclose(void *handle)
197n/a{
198n/a if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
199n/a (((struct mach_header *)handle)->magic == MH_CIGAM))
200n/a {
201n/a error(0, "Can't remove dynamic libraries on darwin");
202n/a return 0;
203n/a }
204n/a if (!NSUnLinkModule(handle, 0))
205n/a {
206n/a error(0, "unable to unlink module %s", NSNameOfModule(handle));
207n/a return 1;
208n/a }
209n/a return 0;
210n/a}
211n/a
212n/a
213n/a/* dlsym, prepend the underscore and call dlsymIntern */
214n/astatic void *darwin_dlsym(void *handle, const char *symbol)
215n/a{
216n/a static char undersym[257]; /* Saves calls to malloc(3) */
217n/a int sym_len = strlen(symbol);
218n/a void *value = NULL;
219n/a char *malloc_sym = NULL;
220n/a
221n/a if (sym_len < 256)
222n/a {
223n/a snprintf(undersym, 256, "_%s", symbol);
224n/a value = dlsymIntern(handle, undersym);
225n/a }
226n/a else
227n/a {
228n/a malloc_sym = malloc(sym_len + 2);
229n/a if (malloc_sym)
230n/a {
231n/a sprintf(malloc_sym, "_%s", symbol);
232n/a value = dlsymIntern(handle, malloc_sym);
233n/a free(malloc_sym);
234n/a }
235n/a else
236n/a {
237n/a error(0, "Unable to allocate memory");
238n/a }
239n/a }
240n/a return value;
241n/a}
242n/a
243n/astatic int darwin_dladdr(const void *handle, Dl_info *info) {
244n/a return 0;
245n/a}
246n/a#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
247n/a
248n/a#if __GNUC__ < 4
249n/a#pragma CALL_ON_LOAD ctypes_dlfcn_init
250n/a#else
251n/astatic void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
252n/astatic
253n/a#endif
254n/avoid ctypes_dlfcn_init(void) {
255n/a if (dlopen != NULL) {
256n/a ctypes_dlsym = dlsym;
257n/a ctypes_dlopen = dlopen;
258n/a ctypes_dlerror = dlerror;
259n/a ctypes_dlclose = dlclose;
260n/a ctypes_dladdr = dladdr;
261n/a } else {
262n/a#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
263n/a ctypes_dlsym = darwin_dlsym;
264n/a ctypes_dlopen = darwin_dlopen;
265n/a ctypes_dlerror = darwin_dlerror;
266n/a ctypes_dlclose = darwin_dlclose;
267n/a ctypes_dladdr = darwin_dladdr;
268n/a#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
269n/a }
270n/a}
271n/a
272n/a#endif /* CTYPES_DARWIN_DLFCN */