source: python/trunk/Python/dynload_shlib.c@ 390

Last change on this file since 390 was 10, checked in by Yuri Dario, 15 years ago

python: merged offline changes.

  • Property svn:eol-style set to native
File size: 3.5 KB
Line 
1
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
10#if defined(__NetBSD__)
11#include <sys/param.h>
12#if (NetBSD < 199712)
13#include <nlist.h>
14#include <link.h>
15#define dlerror() "error in dynamic linking"
16#endif
17#endif /* NetBSD */
18
19#ifdef HAVE_DLFCN_H
20#include <dlfcn.h>
21#else
22#if defined(PYOS_OS2) && defined(PYCC_GCC)
23#ifdef __KLIBC__
24#error "kLIBC has dlfcn.h and shouldn't get here!"
25#endif
26#include "dlfcn.h"
27#endif
28#endif
29
30#if ((defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)) \
31 || (defined(__OS2__) && defined(__KLIBC__))
32#define LEAD_UNDERSCORE "_"
33#else
34#define LEAD_UNDERSCORE ""
35#endif
36
37
38const struct filedescr _PyImport_DynLoadFiletab[] = {
39#ifdef __CYGWIN__
40 {".dll", "rb", C_EXTENSION},
41 {"module.dll", "rb", C_EXTENSION},
42#else
43#if (defined(PYOS_OS2) && defined(PYCC_GCC)) || (defined(__OS2__) && defined(__KLIBC__))
44 {".pyd", "rb", C_EXTENSION},
45 {".dll", "rb", C_EXTENSION},
46#else
47#ifdef __VMS
48 {".exe", "rb", C_EXTENSION},
49 {".EXE", "rb", C_EXTENSION},
50 {"module.exe", "rb", C_EXTENSION},
51 {"MODULE.EXE", "rb", C_EXTENSION},
52#else
53 {".so", "rb", C_EXTENSION},
54 {"module.so", "rb", C_EXTENSION},
55#endif
56#endif
57#endif
58 {0, 0}
59};
60
61static struct {
62 dev_t dev;
63#ifdef __VMS
64 ino_t ino[3];
65#else
66 ino_t ino;
67#endif
68 void *handle;
69} handles[128];
70static int nhandles = 0;
71
72
73dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
74 const char *pathname, FILE *fp)
75{
76 dl_funcptr p;
77 void *handle;
78 char funcname[258];
79 char pathbuf[260];
80 int dlopenflags=0;
81
82 if (strchr(pathname, '/') == NULL) {
83 /* Prefix bare filename with "./" */
84 PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
85 pathname = pathbuf;
86 }
87
88 PyOS_snprintf(funcname, sizeof(funcname),
89 LEAD_UNDERSCORE "init%.200s", shortname);
90
91 if (fp != NULL) {
92 int i;
93 struct stat statb;
94 fstat(fileno(fp), &statb);
95 for (i = 0; i < nhandles; i++) {
96 if (statb.st_dev == handles[i].dev &&
97 statb.st_ino == handles[i].ino) {
98 p = (dl_funcptr) dlsym(handles[i].handle,
99 funcname);
100 return p;
101 }
102 }
103 if (nhandles < 128) {
104 handles[nhandles].dev = statb.st_dev;
105#ifdef __VMS
106 handles[nhandles].ino[0] = statb.st_ino[0];
107 handles[nhandles].ino[1] = statb.st_ino[1];
108 handles[nhandles].ino[2] = statb.st_ino[2];
109#else
110 handles[nhandles].ino = statb.st_ino;
111#endif
112 }
113 }
114
115#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
116 dlopenflags = PyThreadState_GET()->interp->dlopenflags;
117#endif
118
119 if (Py_VerboseFlag)
120 PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
121 dlopenflags);
122
123#ifdef __VMS
124 /* VMS currently don't allow a pathname, use a logical name instead */
125 /* Concatenate 'python_module_' and shortname */
126 /* so "import vms.bar" will use the logical python_module_bar */
127 /* As C module use only one name space this is probably not a */
128 /* important limitation */
129 PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
130 shortname);
131 pathname = pathbuf;
132#endif
133
134#if (defined(PYOS_OS2) && defined(PYCC_GCC))
135 // resolve unixroot
136 if (_realrealpath( pathname, pathbuf, sizeof(pathbuf))!=0)
137 pathname = pathbuf;
138#endif
139
140 handle = dlopen(pathname, dlopenflags);
141
142 if (handle == NULL) {
143 const char *error = dlerror();
144 if (error == NULL)
145 error = "unknown dlopen() error";
146 PyErr_SetString(PyExc_ImportError, error);
147 return NULL;
148 }
149 if (fp != NULL && nhandles < 128)
150 handles[nhandles++].handle = handle;
151 p = (dl_funcptr) dlsym(handle, funcname);
152 return p;
153}
Note: See TracBrowser for help on using the repository browser.