blob: bb90391c0bd1f7849adc0b463a9f373e34597c9e [file] [log] [blame]
Guido van Rossum1ae940a1995-01-02 19:04:15 +00001
2/* Support for dynamic loading of extension modules */
Guido van Rossum1ae940a1995-01-02 19:04:15 +00003
Guido van Rossum79f25d91997-04-29 20:08:16 +00004#include "Python.h"
Guido van Rossum1ae940a1995-01-02 19:04:15 +00005
Guido van Rossum96a8fb71999-12-22 14:09:35 +00006/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
7 supported on this platform. configure will then compile and link in one
8 of the dynload_*.c files, as appropriate. We will call a function in
9 those modules to get a function pointer to the module's init function.
Guido van Rossum1ae940a1995-01-02 19:04:15 +000010*/
Guido van Rossum6ea90921999-12-20 21:20:42 +000011#ifdef HAVE_DYNAMIC_LOADING
Guido van Rossumff4af061996-01-12 01:17:50 +000012
Guido van Rossum96a8fb71999-12-22 14:09:35 +000013#include "importdl.h"
14
Victor Stinner2d322272011-04-04 23:05:53 +020015#ifdef MS_WINDOWS
Nick Coghland5cacbb2015-05-23 22:24:10 +100016extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
17 const char *shortname,
18 PyObject *pathname,
19 FILE *fp);
Victor Stinner2d322272011-04-04 23:05:53 +020020#else
Nick Coghland5cacbb2015-05-23 22:24:10 +100021extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
22 const char *shortname,
23 const char *pathname, FILE *fp);
Victor Stinner2d322272011-04-04 23:05:53 +020024#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +000025
Nick Coghland5cacbb2015-05-23 22:24:10 +100026static const char *ascii_only_prefix = "PyInit";
27static const char *nonascii_prefix = "PyInitU";
28
29/* Get the variable part of a module's export symbol name.
30 * Returns a bytes instance. For non-ASCII-named modules, the name is
31 * encoded as per PEP 489.
32 * The hook_prefix pointer is set to either ascii_only_prefix or
33 * nonascii_prefix, as appropriate.
34 */
35static PyObject *
36get_encoded_name(PyObject *name, const char **hook_prefix) {
37 char *buf;
38 PyObject *tmp;
39 PyObject *encoded = NULL;
40 Py_ssize_t name_len, lastdot, i;
41
42 /* Get the short name (substring after last dot) */
43 name_len = PyUnicode_GetLength(name);
44 lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1);
45 if (lastdot < -1) {
46 return NULL;
47 } else if (lastdot >= 0) {
48 tmp = PyUnicode_Substring(name, lastdot, name_len);
49 if (tmp == NULL)
50 return NULL;
51 name = tmp;
52 /* "name" now holds a new reference to the substring */
53 } else {
54 Py_INCREF(name);
55 }
56
57 /* Encode to ASCII or Punycode, as needed */
58 encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
59 if (encoded != NULL) {
60 *hook_prefix = ascii_only_prefix;
61 } else {
62 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
63 PyErr_Clear();
64 encoded = PyUnicode_AsEncodedString(name, "punycode", NULL);
65 if (encoded == NULL) {
66 goto error;
67 }
68 *hook_prefix = nonascii_prefix;
69 } else {
70 goto error;
71 }
72 }
73
74 buf = PyBytes_AS_STRING(encoded);
75 assert(Py_REFCNT(encoded) == 1);
76 for (i = 0; i < PyBytes_GET_SIZE(encoded) + 1; i++) {
77 if (buf[i] == '-') {
78 buf[i] = '_';
79 }
80 }
81
82 Py_DECREF(name);
83 return encoded;
84error:
85 Py_DECREF(name);
86 Py_XDECREF(encoded);
87 return NULL;
88}
89
Guido van Rossum79f25d91997-04-29 20:08:16 +000090PyObject *
Nick Coghland5cacbb2015-05-23 22:24:10 +100091_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000092{
Victor Stinner2d322272011-04-04 23:05:53 +020093#ifndef MS_WINDOWS
Nick Coghland5cacbb2015-05-23 22:24:10 +100094 PyObject *pathbytes = NULL;
Victor Stinner2d322272011-04-04 23:05:53 +020095#endif
Nick Coghland5cacbb2015-05-23 22:24:10 +100096 PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL;
97 const char *name_buf, *hook_prefix;
98 char *oldcontext;
99 dl_funcptr exportfunc;
100 PyModuleDef *def;
101 PyObject *(*p0)(void);
Guido van Rossum6ea90921999-12-20 21:20:42 +0000102
Nick Coghland5cacbb2015-05-23 22:24:10 +1000103 name_unicode = PyObject_GetAttrString(spec, "name");
104 if (name_unicode == NULL) {
105 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 }
Victor Stinnerfefd70c2011-03-14 15:54:07 -0400107
Nick Coghland5cacbb2015-05-23 22:24:10 +1000108 name = get_encoded_name(name_unicode, &hook_prefix);
109 if (name == NULL) {
110 goto error;
111 }
112 name_buf = PyBytes_AS_STRING(name);
Victor Stinner65b7eff2011-05-07 12:46:05 +0200113
Nick Coghland5cacbb2015-05-23 22:24:10 +1000114 path = PyObject_GetAttrString(spec, "origin");
115 if (path == NULL)
Victor Stinner65b7eff2011-05-07 12:46:05 +0200116 goto error;
117
Victor Stinner2d322272011-04-04 23:05:53 +0200118#ifdef MS_WINDOWS
Nick Coghland5cacbb2015-05-23 22:24:10 +1000119 exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf,
120 path, fp);
Victor Stinner2d322272011-04-04 23:05:53 +0200121#else
Victor Stinnerfefd70c2011-03-14 15:54:07 -0400122 pathbytes = PyUnicode_EncodeFSDefault(path);
123 if (pathbytes == NULL)
Victor Stinner65b7eff2011-05-07 12:46:05 +0200124 goto error;
Nick Coghland5cacbb2015-05-23 22:24:10 +1000125 exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf,
126 PyBytes_AS_STRING(pathbytes),
127 fp);
Victor Stinnerfefd70c2011-03-14 15:54:07 -0400128 Py_DECREF(pathbytes);
Victor Stinner2d322272011-04-04 23:05:53 +0200129#endif
Nick Coghland5cacbb2015-05-23 22:24:10 +1000130
131 if (exportfunc == NULL) {
132 if (!PyErr_Occurred()) {
133 PyObject *msg;
134 msg = PyUnicode_FromFormat(
135 "dynamic module does not define "
136 "module export function (%s_%s)",
137 hook_prefix, name_buf);
138 if (msg == NULL)
139 goto error;
140 PyErr_SetImportError(msg, name_unicode, path);
141 Py_DECREF(msg);
142 }
Victor Stinner65b7eff2011-05-07 12:46:05 +0200143 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000145
Nick Coghland5cacbb2015-05-23 22:24:10 +1000146 p0 = (PyObject *(*)(void))exportfunc;
147
148 /* Package context is needed for single-phase init */
149 oldcontext = _Py_PackageContext;
150 _Py_PackageContext = PyUnicode_AsUTF8(name_unicode);
151 m = p0();
152 _Py_PackageContext = oldcontext;
153
154 if (m == NULL) {
155 if (!PyErr_Occurred()) {
156 PyErr_Format(
157 PyExc_SystemError,
158 "initialization of %s failed without raising an exception",
159 name_buf);
160 }
161 goto error;
162 } else if (PyErr_Occurred()) {
163 PyErr_Clear();
164 PyErr_Format(
165 PyExc_SystemError,
166 "initialization of %s raised unreported exception",
167 name_buf);
168 m = NULL;
169 goto error;
170 }
171 if (Py_TYPE(m) == NULL) {
172 /* This can happen when a PyModuleDef is returned without calling
173 * PyModuleDef_Init on it
174 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 PyErr_Format(PyExc_SystemError,
Nick Coghland5cacbb2015-05-23 22:24:10 +1000176 "init function of %s returned uninitialized object",
177 name_buf);
178 m = NULL; /* prevent segfault in DECREF */
179 goto error;
180 }
181 if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
182 Py_DECREF(name_unicode);
183 Py_DECREF(name);
184 Py_DECREF(path);
185 return PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
186 }
187
188 /* Fall back to single-phase init mechanism */
189
190 if (hook_prefix == nonascii_prefix) {
191 /* don't allow legacy init for non-ASCII module names */
192 PyErr_Format(
193 PyExc_SystemError,
194 "initialization of * did not return PyModuleDef",
195 name_buf);
Victor Stinner65b7eff2011-05-07 12:46:05 +0200196 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 }
Martin v. Löwis1a214512008-06-11 05:26:20 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 /* Remember pointer to module init function. */
200 def = PyModule_GetDef(m);
Christian Heimes7ce57d62013-07-11 13:02:30 +0200201 if (def == NULL) {
202 PyErr_Format(PyExc_SystemError,
203 "initialization of %s did not return an extension "
Nick Coghland5cacbb2015-05-23 22:24:10 +1000204 "module", name_buf);
Christian Heimes848ee092013-07-11 11:22:21 +0200205 goto error;
Christian Heimes7ce57d62013-07-11 13:02:30 +0200206 }
Nick Coghland5cacbb2015-05-23 22:24:10 +1000207 def->m_base.m_init = p0;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 /* Remember the filename as the __file__ attribute */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 if (PyModule_AddObject(m, "__file__", path) < 0)
211 PyErr_Clear(); /* Not important enough to report */
Victor Stinner49d3f252010-10-17 01:24:53 +0000212 else
213 Py_INCREF(path);
Martin v. Löwise81e9b12003-09-04 18:45:59 +0000214
Nick Coghland5cacbb2015-05-23 22:24:10 +1000215 if (_PyImport_FixupExtensionObject(m, name_unicode, path) < 0)
Victor Stinner65b7eff2011-05-07 12:46:05 +0200216 goto error;
Nick Coghland5cacbb2015-05-23 22:24:10 +1000217
218 Py_DECREF(name_unicode);
219 Py_DECREF(name);
220 Py_DECREF(path);
221
Victor Stinnerfefd70c2011-03-14 15:54:07 -0400222 return m;
Victor Stinner65b7eff2011-05-07 12:46:05 +0200223
224error:
Nick Coghland5cacbb2015-05-23 22:24:10 +1000225 Py_DECREF(name_unicode);
226 Py_XDECREF(name);
227 Py_XDECREF(path);
Victor Stinner65b7eff2011-05-07 12:46:05 +0200228 Py_XDECREF(m);
229 return NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000230}
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000231
232#endif /* HAVE_DYNAMIC_LOADING */