]> granicus.if.org Git - python/commitdiff
Patch #412229: Add functions sys.getdlopenflags and sys.setdlopenflags.
authorMartin v. Löwis <martin@v.loewis.de>
Wed, 18 Jul 2001 16:17:16 +0000 (16:17 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Wed, 18 Jul 2001 16:17:16 +0000 (16:17 +0000)
Add dlopenflags to PyInterpreterState, and use it in dlopen calls.

Doc/lib/libsys.tex
Include/pystate.h
Misc/NEWS
Python/dynload_shlib.c
Python/pystate.c
Python/sysmodule.c

index be5a599a45c3e1727f564b4587d46d5ed042caf8..4818cfde3637c39ac68f90f660c1e5e674e85216 100644 (file)
@@ -180,6 +180,13 @@ way to exit a program when an error occurs.
   \versionadded{2.0}
 \end{funcdesc}
 
+\begin{funcdesc}{getdlopenflags}{}
+ Return the current value of the flags that are used for \code{dlopen}
+ calls. The flag constants are defined in the \refmodule{dl} and
+ \module{DLFCN} modules.
+ \versionadded{2.2}
+\end{funcdesc}
+
 \begin{funcdesc}{getrefcount}{object}
 Return the reference count of the \var{object}.  The count returned is
 generally one higher than you might expect, because it includes the
@@ -333,6 +340,20 @@ maximizing responsiveness as well as overhead.
   \versionadded{2.0}
 \end{funcdesc}
 
+\begin{funcdesc}{sertdlopenflags}{n}
+ Set the flags that will be used for \code{dlopen()} calls, i.e. when
+ the interpreter loads extension modules. Among other things, this
+ will enable a lazy resolving of symbols when imporing a module, if
+ called as \code{sys.setdlopenflags(0)}. To share symols across
+ extension modules, call as
+ \code{sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)}.  The symbolic
+ names for the flag modules can be either found in the \refmodule{dl}
+ module, or in the \module{DLFCN} module. If \module{DLFCN} is not
+ available, it can be generated from \code{/usr/include/dlfcn.h} using
+ the \code{h2py} script.
+ \versionadded{2.2}
+\end{funcdesc}
+
 \begin{funcdesc}{setprofile}{profilefunc}
   Set the system's profile function, which allows you to implement a
   Python source code profiler in Python.  See the chapter on the
index 15a264c6789886e876c4be965ac655a16a85183e..41024e84bdd0f7c7dfa4d283dc1fff6ddf057345 100644 (file)
@@ -23,6 +23,9 @@ typedef struct _is {
     PyObject *builtins;
 
     int checkinterval;
+#ifdef HAVE_DLOPEN
+    int dlopenflags;
+#endif
 
 } PyInterpreterState;
 
index 88722bef7d58bd34a48f2c8df17c5e5e05541ae6..55eddedbd71c09ff61aa2dffe3831962530b3aef 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -149,6 +149,9 @@ Core
 
 Library
 
+- The flags used in dlopen calls can now be configured using
+  sys.setdlopenflags and queried using sys.getdlopenflags.
+
 - Fredrik Lundh's xmlrpclib is now a standard library module.  This
   provides full client-side XML-RPC support.  In addition,
   Demo/xmlrpc/ contains two server frameworks (one SocketServer-based,
index 7c8bfd2c3b7e16c5946bcb37b80d54ecaff77a5c..7de3b7d43e4e90569edc84aa79f5809c3aa3c94c 100644 (file)
 #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;
index cca1e7cdbea820ca1c15270971f2a5beea31288c..2f15fdfe94efe5aa4b62837f35ad8ebc7d8095c4 100644 (file)
@@ -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;
index 76d40bfd0badcd293f919960996014babb986a5a..0d6d5a0f9ff6e9c03e9e8f95009d2ac8dcee0b62 100644 (file)
@@ -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\