blob: 78a99568587844af7fb349145c90a371a924ce9d [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>
9#if defined(__NetBSD__) && (NetBSD < 199712)
10#include <nlist.h>
11#include <link.h>
12#define dlerror() "error in dynamic linking"
13#else
14#ifdef HAVE_DLFCN_H
15#include <dlfcn.h>
16#endif
17#endif
18
Martin v. Löwis36546db2001-09-05 14:24:43 +000019#if defined(__OpenBSD__) && !defined(__ELF__)
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000020#define LEAD_UNDERSCORE "_"
21#else
22#define LEAD_UNDERSCORE ""
23#endif
24
Guido van Rossum22a1d361999-12-20 21:18:49 +000025
26const struct filedescr _PyImport_DynLoadFiletab[] = {
Tim Peters98dc0652000-10-05 19:24:26 +000027#ifdef __CYGWIN__
Tim Peters98dc0652000-10-05 19:24:26 +000028 {".dll", "rb", C_EXTENSION},
Guido van Rossumfef12432001-01-10 21:17:27 +000029 {"module.dll", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000030#else
Guido van Rossum22a1d361999-12-20 21:18:49 +000031 {".so", "rb", C_EXTENSION},
32 {"module.so", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000033#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000034 {0, 0}
35};
36
37static struct {
38 dev_t dev;
39 ino_t ino;
40 void *handle;
41} handles[128];
42static int nhandles = 0;
43
44
Guido van Rossum96a8fb71999-12-22 14:09:35 +000045dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000046 const char *pathname, FILE *fp)
47{
48 dl_funcptr p;
49 void *handle;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000050 char funcname[258];
51 char pathbuf[260];
Martin v. Löwisf0473d52001-07-18 16:17:16 +000052 int dlopenflags=0;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000053
54 if (strchr(pathname, '/') == NULL) {
55 /* Prefix bare filename with "./" */
56 sprintf(pathbuf, "./%-.255s", pathname);
57 pathname = pathbuf;
58 }
59
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000060 sprintf(funcname, LEAD_UNDERSCORE "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000061
62 if (fp != NULL) {
63 int i;
64 struct stat statb;
65 fstat(fileno(fp), &statb);
66 for (i = 0; i < nhandles; i++) {
67 if (statb.st_dev == handles[i].dev &&
68 statb.st_ino == handles[i].ino) {
69 p = (dl_funcptr) dlsym(handles[i].handle,
70 funcname);
71 return p;
72 }
73 }
74 if (nhandles < 128) {
75 handles[nhandles].dev = statb.st_dev;
76 handles[nhandles].ino = statb.st_ino;
77 }
78 }
79
Martin v. Löwisf0473d52001-07-18 16:17:16 +000080 dlopenflags = PyThreadState_Get()->interp->dlopenflags;
81
Guido van Rossum22a1d361999-12-20 21:18:49 +000082 if (Py_VerboseFlag)
Martin v. Löwisf0473d52001-07-18 16:17:16 +000083 printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);
84
85 handle = dlopen(pathname, dlopenflags);
86
Guido van Rossum22a1d361999-12-20 21:18:49 +000087 if (handle == NULL) {
88 PyErr_SetString(PyExc_ImportError, dlerror());
89 return NULL;
90 }
91 if (fp != NULL && nhandles < 128)
92 handles[nhandles++].handle = handle;
93 p = (dl_funcptr) dlsym(handle, funcname);
94 return p;
95}