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

Last change on this file since 1291 was 1291, checked in by Silvan Scherrer, 8 years ago

python: add module extention, as some python scripts need that. as example deltarpm

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