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

Last change on this file since 611 was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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