blob: 888fbfcc68c6cd15c749db30450d173748158881 [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001
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>
Martin v. Löwis8a57f002001-10-18 21:24:04 +00009
Martin v. Löwis0eb1ed52001-10-18 11:45:19 +000010#if defined(__NetBSD__)
11#include <sys/param.h>
12#if (NetBSD < 199712)
Guido van Rossum22a1d361999-12-20 21:18:49 +000013#include <nlist.h>
14#include <link.h>
15#define dlerror() "error in dynamic linking"
Martin v. Löwis8a57f002001-10-18 21:24:04 +000016#endif
17#endif /* NetBSD */
18
Guido van Rossum22a1d361999-12-20 21:18:49 +000019#ifdef HAVE_DLFCN_H
20#include <dlfcn.h>
21#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000022
Martin v. Löwis0eb1ed52001-10-18 11:45:19 +000023#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000024#define LEAD_UNDERSCORE "_"
25#else
26#define LEAD_UNDERSCORE ""
27#endif
28
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000029/* The .so extension module ABI tag, supplied by the Makefile via
30 Makefile.pre.in and configure. This is used to discriminate between
31 incompatible .so files so that extensions for different Python builds can
32 live in the same directory. E.g. foomodule.cpython-32.so
33*/
Guido van Rossum22a1d361999-12-20 21:18:49 +000034
Brett Cannon2657df42012-05-04 15:20:40 -040035const char *_PyImport_DynLoadFiletab[] = {
Tim Peters98dc0652000-10-05 19:24:26 +000036#ifdef __CYGWIN__
Brett Cannon2657df42012-05-04 15:20:40 -040037 ".dll",
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000038#else /* !__CYGWIN__ */
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000039#ifdef __VMS
Brett Cannon2657df42012-05-04 15:20:40 -040040 ".exe",
41 ".EXE",
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000042#else /* !__VMS */
Brett Cannon2657df42012-05-04 15:20:40 -040043 "." SOABI ".so",
44 ".abi" PYTHON_ABI_STRING ".so",
45 ".so",
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000046#endif /* __VMS */
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000047#endif /* __CYGWIN__ */
Brett Cannon2657df42012-05-04 15:20:40 -040048 NULL,
Guido van Rossum22a1d361999-12-20 21:18:49 +000049};
50
51static struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 dev_t dev;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000053#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 ino_t ino[3];
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000055#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 ino_t ino;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000057#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 void *handle;
Guido van Rossum22a1d361999-12-20 21:18:49 +000059} handles[128];
60static int nhandles = 0;
61
62
Victor Stinner42040fb2011-02-22 23:16:19 +000063dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 dl_funcptr p;
67 void *handle;
68 char funcname[258];
69 char pathbuf[260];
70 int dlopenflags=0;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 if (strchr(pathname, '/') == NULL) {
73 /* Prefix bare filename with "./" */
74 PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
75 pathname = pathbuf;
76 }
Guido van Rossum96a8fb71999-12-22 14:09:35 +000077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 PyOS_snprintf(funcname, sizeof(funcname),
79 LEAD_UNDERSCORE "PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 if (fp != NULL) {
82 int i;
83 struct stat statb;
Christian Heimes27c4c3e2013-07-20 22:17:55 +020084 if (fstat(fileno(fp), &statb) == -1) {
Benjamin Peterson7d28b6b2013-07-22 22:08:09 -070085 PyErr_SetFromErrno(PyExc_IOError);
86 return NULL;
Christian Heimes27c4c3e2013-07-20 22:17:55 +020087 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 for (i = 0; i < nhandles; i++) {
89 if (statb.st_dev == handles[i].dev &&
90 statb.st_ino == handles[i].ino) {
91 p = (dl_funcptr) dlsym(handles[i].handle,
92 funcname);
93 return p;
94 }
95 }
96 if (nhandles < 128) {
97 handles[nhandles].dev = statb.st_dev;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000098#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 handles[nhandles].ino[0] = statb.st_ino[0];
100 handles[nhandles].ino[1] = statb.st_ino[1];
101 handles[nhandles].ino[2] = statb.st_ino[2];
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000102#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 handles[nhandles].ino = statb.st_ino;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000104#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 }
106 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 dlopenflags = PyThreadState_GET()->interp->dlopenflags;
Martin v. Löwisf0473d52001-07-18 16:17:16 +0000109
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000110#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 /* VMS currently don't allow a pathname, use a logical name instead */
112 /* Concatenate 'python_module_' and shortname */
113 /* so "import vms.bar" will use the logical python_module_bar */
114 /* As C module use only one name space this is probably not a */
115 /* important limitation */
116 PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
117 shortname);
118 pathname = pathbuf;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000119#endif
120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 handle = dlopen(pathname, dlopenflags);
Martin v. Löwisf0473d52001-07-18 16:17:16 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (handle == NULL) {
Victor Stinner3b635cd2012-10-02 00:55:07 +0200124 PyObject *mod_name;
125 PyObject *path;
126 PyObject *error_ob;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 const char *error = dlerror();
128 if (error == NULL)
129 error = "unknown dlopen() error";
Brett Cannonf0434e62012-04-20 15:22:50 -0400130 error_ob = PyUnicode_FromString(error);
Victor Stinner3b635cd2012-10-02 00:55:07 +0200131 if (error_ob == NULL)
132 return NULL;
Brett Cannonf0434e62012-04-20 15:22:50 -0400133 mod_name = PyUnicode_FromString(shortname);
Victor Stinner3b635cd2012-10-02 00:55:07 +0200134 if (mod_name == NULL) {
135 Py_DECREF(error_ob);
136 return NULL;
137 }
138 path = PyUnicode_FromString(pathname);
139 if (path == NULL) {
140 Py_DECREF(error_ob);
141 Py_DECREF(mod_name);
142 return NULL;
143 }
Brett Cannonf0434e62012-04-20 15:22:50 -0400144 PyErr_SetImportError(error_ob, mod_name, path);
Victor Stinner3b635cd2012-10-02 00:55:07 +0200145 Py_DECREF(error_ob);
146 Py_DECREF(mod_name);
147 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 return NULL;
149 }
150 if (fp != NULL && nhandles < 128)
151 handles[nhandles++].handle = handle;
152 p = (dl_funcptr) dlsym(handle, funcname);
153 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000154}