dynload_shlib.c 2.32 KB
Newer Older
1 2 3 4 5 6 7 8

/* Support for dynamic loading of extension modules */

#include "Python.h"
#include "importdl.h"

#include <sys/types.h>
#include <sys/stat.h>
9

10 11 12
#if defined(__NetBSD__)
#include <sys/param.h>
#if (NetBSD < 199712)
13 14 15
#include <nlist.h>
#include <link.h>
#define dlerror() "error in dynamic linking"
16 17 18
#endif
#endif /* NetBSD */

19 20
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
21 22 23 24
#else
#if defined(PYOS_OS2) && defined(PYCC_GCC)
#include "dlfcn.h"
#endif
25 26
#endif

27
#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
28 29 30 31 32
#define LEAD_UNDERSCORE "_"
#else
#define LEAD_UNDERSCORE ""
#endif

33 34

const struct filedescr _PyImport_DynLoadFiletab[] = {
35 36
#ifdef __CYGWIN__
	{".dll", "rb", C_EXTENSION},
37
	{"module.dll", "rb", C_EXTENSION},
38 39 40 41
#else
#if defined(PYOS_OS2) && defined(PYCC_GCC)
	{".pyd", "rb", C_EXTENSION},
	{".dll", "rb", C_EXTENSION},
42
#else
43 44
	{".so", "rb", C_EXTENSION},
	{"module.so", "rb", C_EXTENSION},
45
#endif
46
#endif
47 48 49 50 51 52 53 54 55 56 57
	{0, 0}
};

static struct {
	dev_t dev;
	ino_t ino;
	void *handle;
} handles[128];
static int nhandles = 0;


58
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
59 60 61 62
				    const char *pathname, FILE *fp)
{
	dl_funcptr p;
	void *handle;
63 64
	char funcname[258];
	char pathbuf[260];
65
        int dlopenflags=0;
66 67 68

	if (strchr(pathname, '/') == NULL) {
		/* Prefix bare filename with "./" */
69
		PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
70 71 72
		pathname = pathbuf;
	}

73 74
	PyOS_snprintf(funcname, sizeof(funcname), 
		      LEAD_UNDERSCORE "init%.200s", shortname);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

	if (fp != NULL) {
		int i;
		struct stat statb;
		fstat(fileno(fp), &statb);
		for (i = 0; i < nhandles; i++) {
			if (statb.st_dev == handles[i].dev &&
			    statb.st_ino == handles[i].ino) {
				p = (dl_funcptr) dlsym(handles[i].handle,
						       funcname);
				return p;
			}
		}
		if (nhandles < 128) {
			handles[nhandles].dev = statb.st_dev;
			handles[nhandles].ino = statb.st_ino;
		}
	}

94
#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
95
        dlopenflags = PyThreadState_Get()->interp->dlopenflags;
96
#endif
97

98
	if (Py_VerboseFlag)
99 100 101 102
		printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags);

	handle = dlopen(pathname, dlopenflags);

103 104 105 106 107 108 109 110 111
	if (handle == NULL) {
		PyErr_SetString(PyExc_ImportError, dlerror());
		return NULL;
	}
	if (fp != NULL && nhandles < 128)
		handles[nhandles++].handle = handle;
	p = (dl_funcptr) dlsym(handle, funcname);
	return p;
}