Mercurial > cpython-lru_cache-weakref
view Modules/dlmodule.c @ 16798:258dcafe2d0b legacy-trunk
Gustavo Niemeyer <niemeyer@conectiva.com>:
Fixed recno support (keys are integers rather than strings).
Work around DB bug that cause stdin to be closed by rnopen() when the
DB file needed to exist but did not (no longer segfaults).
This closes SF tracker patch #403445.
Also wrapped some long lines and added whitespace around operators -- FLD.
| author | Fred Drake <fdrake@acm.org> |
|---|---|
| date | Tue, 27 Feb 2001 18:56:46 +0000 |
| parents | 9f86cba4766b |
| children | 8156879fe60d |
line wrap: on
line source
/* dl module */ #include "Python.h" #include <dlfcn.h> #ifndef RTLD_LAZY #define RTLD_LAZY 1 #endif typedef void *PyUnivPtr; typedef struct { PyObject_HEAD PyUnivPtr *dl_handle; } dlobject; staticforward PyTypeObject Dltype; static PyObject *Dlerror; static PyObject * newdlobject(PyUnivPtr *handle) { dlobject *xp; xp = PyObject_New(dlobject, &Dltype); if (xp == NULL) return NULL; xp->dl_handle = handle; return (PyObject *)xp; } static void dl_dealloc(dlobject *xp) { if (xp->dl_handle != NULL) dlclose(xp->dl_handle); PyObject_Del(xp); } static PyObject * dl_close(dlobject *xp, PyObject *args) { if (!PyArg_Parse(args, "")) return NULL; if (xp->dl_handle != NULL) { dlclose(xp->dl_handle); xp->dl_handle = NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * dl_sym(dlobject *xp, PyObject *args) { char *name; PyUnivPtr *func; if (!PyArg_Parse(args, "s", &name)) return NULL; func = dlsym(xp->dl_handle, name); if (func == NULL) { Py_INCREF(Py_None); return Py_None; } return PyInt_FromLong((long)func); } static PyObject * dl_call(dlobject *xp, PyObject *args) { PyObject *name; long (*func)(long, long, long, long, long, long, long, long, long, long); long alist[10]; long res; int i; int n = PyTuple_Size(args); if (n < 1) { PyErr_SetString(PyExc_TypeError, "at least a name is needed"); return NULL; } name = PyTuple_GetItem(args, 0); if (!PyString_Check(name)) { PyErr_SetString(PyExc_TypeError, "function name must be a string"); return NULL; } func = (long (*)(long, long, long, long, long, long, long, long, long, long)) dlsym(xp->dl_handle, PyString_AsString(name)); if (func == NULL) { PyErr_SetString(PyExc_ValueError, dlerror()); return NULL; } if (n-1 > 10) { PyErr_SetString(PyExc_TypeError, "too many arguments (max 10)"); return NULL; } for (i = 1; i < n; i++) { PyObject *v = PyTuple_GetItem(args, i); if (PyInt_Check(v)) alist[i-1] = PyInt_AsLong(v); else if (PyString_Check(v)) alist[i-1] = (long)PyString_AsString(v); else if (v == Py_None) alist[i-1] = (long) ((char *)NULL); else { PyErr_SetString(PyExc_TypeError, "arguments must be int, string or None"); return NULL; } } for (; i <= 10; i++) alist[i-1] = 0; res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4], alist[5], alist[6], alist[7], alist[8], alist[9]); return PyInt_FromLong(res); } static PyMethodDef dlobject_methods[] = { {"call", (PyCFunction)dl_call, 1 /* varargs */}, {"sym", (PyCFunction)dl_sym}, {"close", (PyCFunction)dl_close}, {NULL, NULL} /* Sentinel */ }; static PyObject * dl_getattr(dlobject *xp, char *name) { return Py_FindMethod(dlobject_methods, (PyObject *)xp, name); } static PyTypeObject Dltype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "dl", /*tp_name*/ sizeof(dlobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)dl_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)dl_getattr,/*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ }; static PyObject * dl_open(PyObject *self, PyObject *args) { char *name; int mode; PyUnivPtr *handle; if (PyArg_Parse(args, "z", &name)) mode = RTLD_LAZY; else { PyErr_Clear(); if (!PyArg_Parse(args, "(zi)", &name, &mode)) return NULL; #ifndef RTLD_NOW if (mode != RTLD_LAZY) { PyErr_SetString(PyExc_ValueError, "mode must be 1"); return NULL; } #endif } handle = dlopen(name, mode); if (handle == NULL) { PyErr_SetString(Dlerror, dlerror()); return NULL; } return newdlobject(handle); } static PyMethodDef dl_methods[] = { {"open", dl_open}, {NULL, NULL} /* sentinel */ }; /* From socketmodule.c * Convenience routine to export an integer value. * * Errors are silently ignored, for better or for worse... */ static void insint(PyObject *d, char *name, int value) { PyObject *v = PyInt_FromLong((long) value); if (!v || PyDict_SetItemString(d, name, v)) PyErr_Clear(); Py_XDECREF(v); } void initdl(void) { PyObject *m, *d, *x; if (sizeof(int) != sizeof(long) || sizeof(long) != sizeof(char *)) { PyErr_SetString(PyExc_SystemError, "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)"); return; } /* Create the module and add the functions */ m = Py_InitModule("dl", dl_methods); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); Dlerror = x = PyErr_NewException("dl.error", NULL, NULL); PyDict_SetItemString(d, "error", x); x = PyInt_FromLong((long)RTLD_LAZY); PyDict_SetItemString(d, "RTLD_LAZY", x); #define INSINT(X) insint(d,#X,X) #ifdef RTLD_NOW INSINT(RTLD_NOW); #endif #ifdef RTLD_NOLOAD INSINT(RTLD_NOLOAD); #endif #ifdef RTLD_GLOBAL INSINT(RTLD_GLOBAL); #endif #ifdef RTLD_LOCAL INSINT(RTLD_LOCAL); #endif #ifdef RTLD_PARENT INSINT(RTLD_PARENT); #endif #ifdef RTLD_GROUP INSINT(RTLD_GROUP); #endif #ifdef RTLD_WORLD INSINT(RTLD_WORLD); #endif #ifdef RTLD_NODELETE INSINT(RTLD_NODELETE); #endif }
