/src/cpython3/Python/dynload_shlib.c
Line | Count | Source |
1 | | |
2 | | /* Support for dynamic loading of extension modules */ |
3 | | |
4 | | #include "Python.h" |
5 | | #include "pycore_fileutils.h" // struct _Py_stat_struct |
6 | | #include "pycore_import.h" // _PyImport_GetDLOpenFlags() |
7 | | #include "pycore_importdl.h" |
8 | | #include "pycore_interp.h" // _PyInterpreterState.dlopenflags |
9 | | #include "pycore_pystate.h" // _PyInterpreterState_GET() |
10 | | |
11 | | #include <sys/types.h> |
12 | | #include <sys/stat.h> |
13 | | |
14 | | #if defined(__NetBSD__) |
15 | | #include <sys/param.h> |
16 | | #if (NetBSD < 199712) |
17 | | #include <nlist.h> |
18 | | #include <link.h> |
19 | | #define dlerror() "error in dynamic linking" |
20 | | #endif |
21 | | #endif /* NetBSD */ |
22 | | |
23 | | #ifdef HAVE_DLFCN_H |
24 | | #include <dlfcn.h> |
25 | | #endif |
26 | | |
27 | | #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) |
28 | | #define LEAD_UNDERSCORE "_" |
29 | | #else |
30 | 40 | #define LEAD_UNDERSCORE "" |
31 | | #endif |
32 | | |
33 | | /* The .so extension module ABI tag, supplied by the Makefile via |
34 | | Makefile.pre.in and configure. This is used to discriminate between |
35 | | incompatible .so files so that extensions for different Python builds can |
36 | | live in the same directory. E.g. foomodule.cpython-32.so |
37 | | */ |
38 | | |
39 | | const char *_PyImport_DynLoadFiletab[] = { |
40 | | #ifdef __CYGWIN__ |
41 | | "." SOABI ".dll", |
42 | | ".dll", |
43 | | #else /* !__CYGWIN__ */ |
44 | | "." SOABI ".so", |
45 | | #ifdef ALT_SOABI |
46 | | "." ALT_SOABI ".so", |
47 | | #endif |
48 | | #ifndef Py_GIL_DISABLED |
49 | | #ifdef SOABI_PLATFORM |
50 | | ".abi" PYTHON_ABI_STRING "-" SOABI_PLATFORM ".so", |
51 | | #endif /* SOABI_PLATFORM */ |
52 | | ".abi" PYTHON_ABI_STRING ".so", |
53 | | #endif /* Py_GIL_DISABLED */ |
54 | | #ifdef SOABI_PLATFORM |
55 | | ".abi" PYTHON_ABI_STRING "t-" SOABI_PLATFORM ".so", |
56 | | #endif /* SOABI_PLATFORM */ |
57 | | ".abi" PYTHON_ABI_STRING "t.so", |
58 | | ".so", |
59 | | #endif /* __CYGWIN__ */ |
60 | | NULL, |
61 | | }; |
62 | | |
63 | | |
64 | | dl_funcptr |
65 | | _PyImport_FindSharedFuncptr(const char *prefix, |
66 | | const char *shortname, |
67 | | const char *pathname, FILE *fp) |
68 | 40 | { |
69 | 40 | dl_funcptr p; |
70 | 40 | void *handle; |
71 | 40 | char funcname[258]; |
72 | 40 | char pathbuf[260]; |
73 | 40 | int dlopenflags=0; |
74 | | |
75 | 40 | if (strchr(pathname, '/') == NULL) { |
76 | | /* Prefix bare filename with "./" */ |
77 | 0 | PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); |
78 | 0 | pathname = pathbuf; |
79 | 0 | } |
80 | | |
81 | 40 | PyOS_snprintf(funcname, sizeof(funcname), |
82 | 40 | LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); |
83 | | |
84 | 40 | if (fp != NULL) { |
85 | 0 | struct _Py_stat_struct status; |
86 | 0 | if (_Py_fstat(fileno(fp), &status) == -1) |
87 | 0 | return NULL; |
88 | 0 | } |
89 | | |
90 | 40 | dlopenflags = _PyImport_GetDLOpenFlags(_PyInterpreterState_GET()); |
91 | | |
92 | 40 | handle = dlopen(pathname, dlopenflags); |
93 | | |
94 | 40 | if (handle == NULL) { |
95 | 0 | PyObject *mod_name; |
96 | 0 | PyObject *path; |
97 | 0 | PyObject *error_ob; |
98 | 0 | const char *error = dlerror(); |
99 | 0 | if (error == NULL) |
100 | 0 | error = "unknown dlopen() error"; |
101 | 0 | error_ob = PyUnicode_DecodeLocale(error, "surrogateescape"); |
102 | 0 | if (error_ob == NULL) |
103 | 0 | return NULL; |
104 | 0 | mod_name = PyUnicode_FromString(shortname); |
105 | 0 | if (mod_name == NULL) { |
106 | 0 | Py_DECREF(error_ob); |
107 | 0 | return NULL; |
108 | 0 | } |
109 | 0 | path = PyUnicode_DecodeFSDefault(pathname); |
110 | 0 | if (path == NULL) { |
111 | 0 | Py_DECREF(error_ob); |
112 | 0 | Py_DECREF(mod_name); |
113 | 0 | return NULL; |
114 | 0 | } |
115 | 0 | PyErr_SetImportError(error_ob, mod_name, path); |
116 | 0 | Py_DECREF(error_ob); |
117 | 0 | Py_DECREF(mod_name); |
118 | 0 | Py_DECREF(path); |
119 | 0 | return NULL; |
120 | 0 | } |
121 | 40 | p = (dl_funcptr) dlsym(handle, funcname); |
122 | 40 | return p; |
123 | 40 | } |