https://github.com/python/cpython
Tip revision: c912af833905c3bb172f268410d6bcc5865f488c authored by Larry Hastings on 24 July 2017, 01:16:33 UTC
Version bump and copyright year fixes for 3.4.7rc1.
Version bump and copyright year fixes for 3.4.7rc1.
Tip revision: c912af8
dynload_shlib.c
/* Support for dynamic loading of extension modules */
#include "Python.h"
#include "importdl.h"
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__NetBSD__)
#include <sys/param.h>
#if (NetBSD < 199712)
#include <nlist.h>
#include <link.h>
#define dlerror() "error in dynamic linking"
#endif
#endif /* NetBSD */
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
#define LEAD_UNDERSCORE "_"
#else
#define LEAD_UNDERSCORE ""
#endif
/* The .so extension module ABI tag, supplied by the Makefile via
Makefile.pre.in and configure. This is used to discriminate between
incompatible .so files so that extensions for different Python builds can
live in the same directory. E.g. foomodule.cpython-32.so
*/
const char *_PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
".dll",
#else /* !__CYGWIN__ */
"." SOABI ".so",
".abi" PYTHON_ABI_STRING ".so",
".so",
#endif /* __CYGWIN__ */
NULL,
};
static struct {
dev_t dev;
ino_t ino;
void *handle;
} handles[128];
static int nhandles = 0;
dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp)
{
dl_funcptr p;
void *handle;
char funcname[258];
char pathbuf[260];
int dlopenflags=0;
if (strchr(pathname, '/') == NULL) {
/* Prefix bare filename with "./" */
PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
pathname = pathbuf;
}
PyOS_snprintf(funcname, sizeof(funcname),
LEAD_UNDERSCORE "PyInit_%.200s", shortname);
if (fp != NULL) {
int i;
struct stat statb;
if (fstat(fileno(fp), &statb) == -1) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
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;
}
}
dlopenflags = PyThreadState_GET()->interp->dlopenflags;
handle = dlopen(pathname, dlopenflags);
if (handle == NULL) {
PyObject *mod_name;
PyObject *path;
PyObject *error_ob;
const char *error = dlerror();
if (error == NULL)
error = "unknown dlopen() error";
error_ob = PyUnicode_FromString(error);
if (error_ob == NULL)
return NULL;
mod_name = PyUnicode_FromString(shortname);
if (mod_name == NULL) {
Py_DECREF(error_ob);
return NULL;
}
path = PyUnicode_FromString(pathname);
if (path == NULL) {
Py_DECREF(error_ob);
Py_DECREF(mod_name);
return NULL;
}
PyErr_SetImportError(error_ob, mod_name, path);
Py_DECREF(error_ob);
Py_DECREF(mod_name);
Py_DECREF(path);
return NULL;
}
if (fp != NULL && nhandles < 128)
handles[nhandles++].handle = handle;
p = (dl_funcptr) dlsym(handle, funcname);
return p;
}