blob: 7c8bfd2c3b7e16c5946bcb37b80d54ecaff77a5c [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
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000019#ifdef __OpenBSD__
20#define LEAD_UNDERSCORE "_"
21#else
22#define LEAD_UNDERSCORE ""
23#endif
24
Guido van Rossum22a1d361999-12-20 21:18:49 +000025#ifndef RTLD_LAZY
26#define RTLD_LAZY 1
27#endif
28
29
30const struct filedescr _PyImport_DynLoadFiletab[] = {
Tim Peters98dc0652000-10-05 19:24:26 +000031#ifdef __CYGWIN__
Tim Peters98dc0652000-10-05 19:24:26 +000032 {".dll", "rb", C_EXTENSION},
Guido van Rossumfef12432001-01-10 21:17:27 +000033 {"module.dll", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000034#else
Guido van Rossum22a1d361999-12-20 21:18:49 +000035 {".so", "rb", C_EXTENSION},
36 {"module.so", "rb", C_EXTENSION},
Tim Peters98dc0652000-10-05 19:24:26 +000037#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000038 {0, 0}
39};
40
41static struct {
42 dev_t dev;
43 ino_t ino;
44 void *handle;
45} handles[128];
46static int nhandles = 0;
47
48
Guido van Rossum96a8fb71999-12-22 14:09:35 +000049dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000050 const char *pathname, FILE *fp)
51{
52 dl_funcptr p;
53 void *handle;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000054 char funcname[258];
55 char pathbuf[260];
56
57 if (strchr(pathname, '/') == NULL) {
58 /* Prefix bare filename with "./" */
59 sprintf(pathbuf, "./%-.255s", pathname);
60 pathname = pathbuf;
61 }
62
Guido van Rossumc8fcdcb2000-10-25 22:07:45 +000063 sprintf(funcname, LEAD_UNDERSCORE "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000064
65 if (fp != NULL) {
66 int i;
67 struct stat statb;
68 fstat(fileno(fp), &statb);
69 for (i = 0; i < nhandles; i++) {
70 if (statb.st_dev == handles[i].dev &&
71 statb.st_ino == handles[i].ino) {
72 p = (dl_funcptr) dlsym(handles[i].handle,
73 funcname);
74 return p;
75 }
76 }
77 if (nhandles < 128) {
78 handles[nhandles].dev = statb.st_dev;
79 handles[nhandles].ino = statb.st_ino;
80 }
81 }
82
83#ifdef RTLD_NOW
84 /* RTLD_NOW: resolve externals now
85 (i.e. core dump now if some are missing) */
86 handle = dlopen(pathname, RTLD_NOW);
87#else
88 if (Py_VerboseFlag)
89 printf("dlopen(\"%s\", %d);\n", pathname,
90 RTLD_LAZY);
91 handle = dlopen(pathname, RTLD_LAZY);
92#endif /* RTLD_NOW */
93 if (handle == NULL) {
94 PyErr_SetString(PyExc_ImportError, dlerror());
95 return NULL;
96 }
97 if (fp != NULL && nhandles < 128)
98 handles[nhandles++].handle = handle;
99 p = (dl_funcptr) dlsym(handle, funcname);
100 return p;
101}