|
1 |
|
2 /* Support for dynamic loading of extension modules */ |
|
3 |
|
4 #include "Python.h" |
|
5 #include "importdl.h" |
|
6 |
|
7 #include <sys/types.h> |
|
8 #include <sys/stat.h> |
|
9 |
|
10 #if defined(__NetBSD__) |
|
11 #include <sys/param.h> |
|
12 #if (NetBSD < 199712) |
|
13 #include <nlist.h> |
|
14 #include <link.h> |
|
15 #define dlerror() "error in dynamic linking" |
|
16 #endif |
|
17 #endif /* NetBSD */ |
|
18 |
|
19 #ifdef HAVE_DLFCN_H |
|
20 #include <dlfcn.h> |
|
21 #else |
|
22 #if defined(PYOS_OS2) && defined(PYCC_GCC) |
|
23 #include "dlfcn.h" |
|
24 #endif |
|
25 #endif |
|
26 |
|
27 #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) |
|
28 #define LEAD_UNDERSCORE "_" |
|
29 #else |
|
30 #define LEAD_UNDERSCORE "" |
|
31 #endif |
|
32 |
|
33 |
|
34 const struct filedescr _PyImport_DynLoadFiletab[] = { |
|
35 #ifdef __CYGWIN__ |
|
36 {".dll", "rb", C_EXTENSION}, |
|
37 {"module.dll", "rb", C_EXTENSION}, |
|
38 #else |
|
39 #if defined(PYOS_OS2) && defined(PYCC_GCC) |
|
40 {".pyd", "rb", C_EXTENSION}, |
|
41 {".dll", "rb", C_EXTENSION}, |
|
42 #else |
|
43 #ifdef __VMS |
|
44 {".exe", "rb", C_EXTENSION}, |
|
45 {".EXE", "rb", C_EXTENSION}, |
|
46 {"module.exe", "rb", C_EXTENSION}, |
|
47 {"MODULE.EXE", "rb", C_EXTENSION}, |
|
48 #else |
|
49 {".so", "rb", C_EXTENSION}, |
|
50 {"module.so", "rb", C_EXTENSION}, |
|
51 #endif |
|
52 #endif |
|
53 #endif |
|
54 {0, 0} |
|
55 }; |
|
56 |
|
57 static struct { |
|
58 dev_t dev; |
|
59 #ifdef __VMS |
|
60 ino_t ino[3]; |
|
61 #else |
|
62 ino_t ino; |
|
63 #endif |
|
64 void *handle; |
|
65 } handles[128]; |
|
66 static int nhandles = 0; |
|
67 |
|
68 |
|
69 dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, |
|
70 const char *pathname, FILE *fp) |
|
71 { |
|
72 dl_funcptr p; |
|
73 void *handle; |
|
74 char funcname[258]; |
|
75 char pathbuf[260]; |
|
76 int dlopenflags=0; |
|
77 |
|
78 if (strchr(pathname, '/') == NULL) { |
|
79 /* Prefix bare filename with "./" */ |
|
80 PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); |
|
81 pathname = pathbuf; |
|
82 } |
|
83 |
|
84 PyOS_snprintf(funcname, sizeof(funcname), |
|
85 LEAD_UNDERSCORE "init%.200s", shortname); |
|
86 |
|
87 if (fp != NULL) { |
|
88 int i; |
|
89 struct stat statb; |
|
90 fstat(fileno(fp), &statb); |
|
91 for (i = 0; i < nhandles; i++) { |
|
92 if (statb.st_dev == handles[i].dev && |
|
93 statb.st_ino == handles[i].ino) { |
|
94 p = (dl_funcptr) dlsym(handles[i].handle, |
|
95 funcname); |
|
96 return p; |
|
97 } |
|
98 } |
|
99 if (nhandles < 128) { |
|
100 handles[nhandles].dev = statb.st_dev; |
|
101 #ifdef __VMS |
|
102 handles[nhandles].ino[0] = statb.st_ino[0]; |
|
103 handles[nhandles].ino[1] = statb.st_ino[1]; |
|
104 handles[nhandles].ino[2] = statb.st_ino[2]; |
|
105 #else |
|
106 handles[nhandles].ino = statb.st_ino; |
|
107 #endif |
|
108 } |
|
109 } |
|
110 |
|
111 #if !(defined(PYOS_OS2) && defined(PYCC_GCC)) |
|
112 dlopenflags = PyThreadState_GET()->interp->dlopenflags; |
|
113 #endif |
|
114 |
|
115 if (Py_VerboseFlag) |
|
116 PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname, |
|
117 dlopenflags); |
|
118 |
|
119 #ifdef __VMS |
|
120 /* VMS currently don't allow a pathname, use a logical name instead */ |
|
121 /* Concatenate 'python_module_' and shortname */ |
|
122 /* so "import vms.bar" will use the logical python_module_bar */ |
|
123 /* As C module use only one name space this is probably not a */ |
|
124 /* important limitation */ |
|
125 PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s", |
|
126 shortname); |
|
127 pathname = pathbuf; |
|
128 #endif |
|
129 |
|
130 handle = dlopen(pathname, dlopenflags); |
|
131 |
|
132 if (handle == NULL) { |
|
133 const char *error = dlerror(); |
|
134 if (error == NULL) |
|
135 error = "unknown dlopen() error"; |
|
136 PyErr_SetString(PyExc_ImportError, error); |
|
137 return NULL; |
|
138 } |
|
139 if (fp != NULL && nhandles < 128) |
|
140 handles[nhandles++].handle = handle; |
|
141 p = (dl_funcptr) dlsym(handle, funcname); |
|
142 return p; |
|
143 } |