blob: 61674ba555a2575cb7d8bacdfefd54f605bb041f [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
Guido van Rossum22a1d361999-12-20 21:18:49 +000033
34const struct filedescr _PyImport_DynLoadFiletab[] = {
Tim Peters98dc0652000-10-05 19:24:26 +000035#ifdef __CYGWIN__
Tim Peters98dc0652000-10-05 19:24:26 +000036 {".dll", "rb", C_EXTENSION},
Guido van Rossumfef12432001-01-10 21:17:27 +000037 {"module.dll", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000038#else
Andrew MacIntyred9400542002-02-26 11:41:34 +000039#if defined(PYOS_OS2) && defined(PYCC_GCC)
40 {".pyd", "rb", C_EXTENSION},
41 {".dll", "rb", C_EXTENSION},
42#else
Guido van Rossum22a1d361999-12-20 21:18:49 +000043 {".so", "rb", C_EXTENSION},
44 {"module.so", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000045#endif
Andrew MacIntyred9400542002-02-26 11:41:34 +000046#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000047 {0, 0}
48};
49
50static struct {
51 dev_t dev;
52 ino_t ino;
53 void *handle;
54} handles[128];
55static int nhandles = 0;
56
57
Guido van Rossum96a8fb71999-12-22 14:09:35 +000058dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000059 const char *pathname, FILE *fp)
60{
61 dl_funcptr p;
62 void *handle;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000063 char funcname[258];
64 char pathbuf[260];
Martin v. Löwisf0473d52001-07-18 16:17:16 +000065 int dlopenflags=0;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000066
67 if (strchr(pathname, '/') == NULL) {
68 /* Prefix bare filename with "./" */
Jeremy Hylton518ab1c2001-11-28 20:42:20 +000069 PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
Guido van Rossum96a8fb71999-12-22 14:09:35 +000070 pathname = pathbuf;
71 }
72
Jeremy Hylton518ab1c2001-11-28 20:42:20 +000073 PyOS_snprintf(funcname, sizeof(funcname),
74 LEAD_UNDERSCORE "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000075
76 if (fp != NULL) {
77 int i;
78 struct stat statb;
79 fstat(fileno(fp), &statb);
80 for (i = 0; i < nhandles; i++) {
81 if (statb.st_dev == handles[i].dev &&
82 statb.st_ino == handles[i].ino) {
83 p = (dl_funcptr) dlsym(handles[i].handle,
84 funcname);
85 return p;
86 }
87 }
88 if (nhandles < 128) {
89 handles[nhandles].dev = statb.st_dev;
90 handles[nhandles].ino = statb.st_ino;
91 }
92 }
93
Andrew MacIntyred9400542002-02-26 11:41:34 +000094#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
Martin v. Löwisf0473d52001-07-18 16:17:16 +000095 dlopenflags = PyThreadState_Get()->interp->dlopenflags;
Andrew MacIntyred9400542002-02-26 11:41:34 +000096#endif
Martin v. Löwisf0473d52001-07-18 16:17:16 +000097
Guido van Rossum22a1d361999-12-20 21:18:49 +000098 if (Py_VerboseFlag)
Martin v. Löwisf0473d52001-07-18 16:17:16 +000099 printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);
100
101 handle = dlopen(pathname, dlopenflags);
102
Guido van Rossum22a1d361999-12-20 21:18:49 +0000103 if (handle == NULL) {
104 PyErr_SetString(PyExc_ImportError, dlerror());
105 return NULL;
106 }
107 if (fp != NULL && nhandles < 128)
108 handles[nhandles++].handle = handle;
109 p = (dl_funcptr) dlsym(handle, funcname);
110 return p;
111}