blob: 7ea510e862dfabd2834779f1d2338f61b903ef72 [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>
Andrew MacIntyred9400542002-02-26 11:41:34 +000021#else
22#if defined(PYOS_OS2) && defined(PYCC_GCC)
23#include "dlfcn.h"
24#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000025#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000026
Martin v. Löwis0eb1ed52001-10-18 11:45:19 +000027#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000028#define LEAD_UNDERSCORE "_"
29#else
30#define LEAD_UNDERSCORE ""
31#endif
32
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000033/* 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*/
Guido van Rossum22a1d361999-12-20 21:18:49 +000038
39const struct filedescr _PyImport_DynLoadFiletab[] = {
Tim Peters98dc0652000-10-05 19:24:26 +000040#ifdef __CYGWIN__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 {".dll", "rb", C_EXTENSION},
42 {"module.dll", "rb", C_EXTENSION},
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000043#else /* !__CYGWIN__ */
Andrew MacIntyred9400542002-02-26 11:41:34 +000044#if defined(PYOS_OS2) && defined(PYCC_GCC)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 {".pyd", "rb", C_EXTENSION},
46 {".dll", "rb", C_EXTENSION},
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000047#else /* !(defined(PYOS_OS2) && defined(PYCC_GCC)) */
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000048#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 {".exe", "rb", C_EXTENSION},
50 {".EXE", "rb", C_EXTENSION},
51 {"module.exe", "rb", C_EXTENSION},
52 {"MODULE.EXE", "rb", C_EXTENSION},
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000053#else /* !__VMS */
54 {"." SOABI ".so", "rb", C_EXTENSION},
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000055 {"module." SOABI ".so", "rb", C_EXTENSION},
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000056 {".abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION},
57 {"module.abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION},
Matthias Klosef69af1e2010-09-08 16:22:10 +000058 {".so", "rb", C_EXTENSION},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 {"module.so", "rb", C_EXTENSION},
Barry Warsaw35f3a2c2010-09-03 18:30:30 +000060#endif /* __VMS */
61#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
62#endif /* __CYGWIN__ */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 {0, 0}
Guido van Rossum22a1d361999-12-20 21:18:49 +000064};
65
66static struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 dev_t dev;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000068#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 ino_t ino[3];
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000070#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 ino_t ino;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000072#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 void *handle;
Guido van Rossum22a1d361999-12-20 21:18:49 +000074} handles[128];
75static int nhandles = 0;
76
77
Guido van Rossum96a8fb71999-12-22 14:09:35 +000078dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 const char *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +000080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 dl_funcptr p;
82 void *handle;
83 char funcname[258];
84 char pathbuf[260];
85 int dlopenflags=0;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 if (strchr(pathname, '/') == NULL) {
88 /* Prefix bare filename with "./" */
89 PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
90 pathname = pathbuf;
91 }
Guido van Rossum96a8fb71999-12-22 14:09:35 +000092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyOS_snprintf(funcname, sizeof(funcname),
94 LEAD_UNDERSCORE "PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 if (fp != NULL) {
97 int i;
98 struct stat statb;
99 fstat(fileno(fp), &statb);
100 for (i = 0; i < nhandles; i++) {
101 if (statb.st_dev == handles[i].dev &&
102 statb.st_ino == handles[i].ino) {
103 p = (dl_funcptr) dlsym(handles[i].handle,
104 funcname);
105 return p;
106 }
107 }
108 if (nhandles < 128) {
109 handles[nhandles].dev = statb.st_dev;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000110#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 handles[nhandles].ino[0] = statb.st_ino[0];
112 handles[nhandles].ino[1] = statb.st_ino[1];
113 handles[nhandles].ino[2] = statb.st_ino[2];
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000114#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 handles[nhandles].ino = statb.st_ino;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000116#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 }
118 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000119
Andrew MacIntyred9400542002-02-26 11:41:34 +0000120#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 dlopenflags = PyThreadState_GET()->interp->dlopenflags;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000122#endif
Martin v. Löwisf0473d52001-07-18 16:17:16 +0000123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 if (Py_VerboseFlag)
125 PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
126 dlopenflags);
Martin v. Löwisf0473d52001-07-18 16:17:16 +0000127
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000128#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* VMS currently don't allow a pathname, use a logical name instead */
130 /* Concatenate 'python_module_' and shortname */
131 /* so "import vms.bar" will use the logical python_module_bar */
132 /* As C module use only one name space this is probably not a */
133 /* important limitation */
134 PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
135 shortname);
136 pathname = pathbuf;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000137#endif
138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 handle = dlopen(pathname, dlopenflags);
Martin v. Löwisf0473d52001-07-18 16:17:16 +0000140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 if (handle == NULL) {
142 const char *error = dlerror();
143 if (error == NULL)
144 error = "unknown dlopen() error";
145 PyErr_SetString(PyExc_ImportError, error);
146 return NULL;
147 }
148 if (fp != NULL && nhandles < 128)
149 handles[nhandles++].handle = handle;
150 p = (dl_funcptr) dlsym(handle, funcname);
151 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000152}