PageRenderTime 38ms CodeModel.GetById 14ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 1ms

/Python/dynload_shlib.c

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