diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/dynload_shlib.c | 20 | ||||
-rw-r--r-- | Python/pystate.c | 17 | ||||
-rw-r--r-- | Python/sysmodule.c | 52 |
3 files changed, 76 insertions, 13 deletions
diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 7c8bfd2..7de3b7d 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -22,10 +22,6 @@ #define LEAD_UNDERSCORE "" #endif -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif - const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ @@ -53,6 +49,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, void *handle; char funcname[258]; char pathbuf[260]; + int dlopenflags=0; if (strchr(pathname, '/') == NULL) { /* Prefix bare filename with "./" */ @@ -80,16 +77,13 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, } } -#ifdef RTLD_NOW - /* RTLD_NOW: resolve externals now - (i.e. core dump now if some are missing) */ - handle = dlopen(pathname, RTLD_NOW); -#else + dlopenflags = PyThreadState_Get()->interp->dlopenflags; + if (Py_VerboseFlag) - printf("dlopen(\"%s\", %d);\n", pathname, - RTLD_LAZY); - handle = dlopen(pathname, RTLD_LAZY); -#endif /* RTLD_NOW */ + printf("dlopen(\"%s\", %x);\n", pathname, dlopenflags); + + handle = dlopen(pathname, dlopenflags); + if (handle == NULL) { PyErr_SetString(PyExc_ImportError, dlerror()); return NULL; diff --git a/Python/pystate.c b/Python/pystate.c index cca1e7c..2f15fdf 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,16 @@ #include "Python.h" +#ifdef HAVE_DLOPEN +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#endif +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif +#endif + + #define ZAP(x) { \ PyObject *tmp = (PyObject *)(x); \ (x) = NULL; \ @@ -39,6 +49,13 @@ PyInterpreterState_New(void) interp->builtins = NULL; interp->checkinterval = 10; interp->tstate_head = NULL; +#ifdef HAVE_DLOPEN +#ifdef RTLD_NOW + interp->dlopenflags = RTLD_NOW; +#else + interp->dlopenflags = RTLD_LAZY; +#endif +#endif HEAD_LOCK(); interp->next = interp_head; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 76d40bf..0d6d5a0 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -394,6 +394,48 @@ Return the current value of the recursion limit, the maximum depth\n\ of the Python interpreter stack. This limit prevents infinite\n\ recursion from causing an overflow of the C stack and crashing Python."; +#ifdef HAVE_DLOPEN +static PyObject * +sys_setdlopenflags(PyObject *self, PyObject *args) +{ + int new_val; + PyThreadState *tstate = PyThreadState_Get(); + if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val)) + return NULL; + if (!tstate) + return NULL; + tstate->interp->dlopenflags = new_val; + Py_INCREF(Py_None); + return Py_None; +} + +static char setdlopenflags_doc[] = +"setdlopenflags(n) -> None\n\ +\n\ +Set the flags that will be used for dlopen() calls. Among other\n\ +things, this will enable a lazy resolving of symbols when imporing\n\ +a module, if called as sys.setdlopenflags(0)\n\ +To share symols across extension modules, call as\n\ +sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)"; + +static PyObject * +sys_getdlopenflags(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_Get(); + if (!PyArg_ParseTuple(args, ":getdlopenflags")) + return NULL; + if (!tstate) + return NULL; + return PyInt_FromLong(tstate->interp->dlopenflags); +} + +static char getdlopenflags_doc[] = +"getdlopenflags() -> int\n\ +\n\ +Return the current value of the flags that are used for dlopen()\n\ +calls. The flag constants are defined in the dl module."; +#endif + #ifdef USE_MALLOPT /* Link with -lmalloc (or -lmpc) on an SGI */ #include <malloc.h> @@ -501,6 +543,10 @@ static PyMethodDef sys_methods[] = { {"exit", sys_exit, 0, exit_doc}, {"getdefaultencoding", sys_getdefaultencoding, 1, getdefaultencoding_doc}, +#ifdef HAVE_DLOPEN + {"getdlopenflags", sys_getdlopenflags, 1, + getdlopenflags_doc}, +#endif #ifdef COUNT_ALLOCS {"getcounts", sys_getcounts, 1}, #endif @@ -522,6 +568,10 @@ static PyMethodDef sys_methods[] = { setdefaultencoding_doc}, {"setcheckinterval", sys_setcheckinterval, 1, setcheckinterval_doc}, +#ifdef HAVE_DLOPEN + {"setdlopenflags", sys_setdlopenflags, 1, + setdlopenflags_doc}, +#endif {"setprofile", sys_setprofile, 0, setprofile_doc}, {"setrecursionlimit", sys_setrecursionlimit, 1, setrecursionlimit_doc}, @@ -659,9 +709,11 @@ displayhook() -- print an object to the screen, and save it in __builtin__._\n\ excepthook() -- print an exception and its traceback to sys.stderr\n\ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ +getdlopenflags() -- returns flags to be used for dlopen() calls\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ getrecursionlimit() -- return the max recursion depth for the interpreter\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ +setdlopenflags() -- set the flags to be used for dlopen() calls\n\ setprofile() -- set the global profiling function\n\ setrecursionlimit() -- set the max recursion depth for the interpreter\n\ settrace() -- set the global debug tracing function\n\ |