12 typedef void *PyUnivPtr
;
18 static PyTypeObject Dltype
;
20 static PyObject
*Dlerror
;
23 newdlobject(PyUnivPtr
*handle
)
26 xp
= PyObject_New(dlobject
, &Dltype
);
29 xp
->dl_handle
= handle
;
30 return (PyObject
*)xp
;
34 dl_dealloc(dlobject
*xp
)
36 if (xp
->dl_handle
!= NULL
)
37 dlclose(xp
->dl_handle
);
42 dl_close(dlobject
*xp
)
44 if (xp
->dl_handle
!= NULL
) {
45 dlclose(xp
->dl_handle
);
53 dl_sym(dlobject
*xp
, PyObject
*args
)
57 if (PyString_Check(args
)) {
58 name
= PyString_AS_STRING(args
);
60 PyErr_Format(PyExc_TypeError
, "expected string, found %.200s",
61 args
->ob_type
->tp_name
);
64 func
= dlsym(xp
->dl_handle
, name
);
69 return PyInt_FromLong((long)func
);
73 dl_call(dlobject
*xp
, PyObject
*args
)
76 long (*func
)(long, long, long, long, long,
77 long, long, long, long, long);
81 int n
= PyTuple_Size(args
);
83 PyErr_SetString(PyExc_TypeError
, "at least a name is needed");
86 name
= PyTuple_GetItem(args
, 0);
87 if (!PyString_Check(name
)) {
88 PyErr_SetString(PyExc_TypeError
,
89 "function name must be a string");
92 func
= (long (*)(long, long, long, long, long,
93 long, long, long, long, long))
94 dlsym(xp
->dl_handle
, PyString_AsString(name
));
96 PyErr_SetString(PyExc_ValueError
, dlerror());
100 PyErr_SetString(PyExc_TypeError
,
101 "too many arguments (max 10)");
104 for (i
= 1; i
< n
; i
++) {
105 PyObject
*v
= PyTuple_GetItem(args
, i
);
107 alist
[i
-1] = PyInt_AsLong(v
);
108 else if (PyString_Check(v
))
109 alist
[i
-1] = (long)PyString_AsString(v
);
110 else if (v
== Py_None
)
111 alist
[i
-1] = (long) ((char *)NULL
);
113 PyErr_SetString(PyExc_TypeError
,
114 "arguments must be int, string or None");
120 res
= (*func
)(alist
[0], alist
[1], alist
[2], alist
[3], alist
[4],
121 alist
[5], alist
[6], alist
[7], alist
[8], alist
[9]);
122 return PyInt_FromLong(res
);
125 static PyMethodDef dlobject_methods
[] = {
126 {"call", (PyCFunction
)dl_call
, METH_VARARGS
},
127 {"sym", (PyCFunction
)dl_sym
, METH_O
},
128 {"close", (PyCFunction
)dl_close
, METH_NOARGS
},
129 {NULL
, NULL
} /* Sentinel */
133 dl_getattr(dlobject
*xp
, char *name
)
135 return Py_FindMethod(dlobject_methods
, (PyObject
*)xp
, name
);
139 static PyTypeObject Dltype
= {
140 PyObject_HEAD_INIT(NULL
)
143 sizeof(dlobject
), /*tp_basicsize*/
146 (destructor
)dl_dealloc
, /*tp_dealloc*/
148 (getattrfunc
)dl_getattr
,/*tp_getattr*/
153 0, /*tp_as_sequence*/
159 dl_open(PyObject
*self
, PyObject
*args
)
164 if (sizeof(int) != sizeof(long) ||
165 sizeof(long) != sizeof(char *)) {
166 PyErr_SetString(PyExc_SystemError
,
167 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
171 if (PyArg_ParseTuple(args
, "z:open", &name
))
175 if (!PyArg_ParseTuple(args
, "zi:open", &name
, &mode
))
178 if (mode
!= RTLD_LAZY
) {
179 PyErr_SetString(PyExc_ValueError
, "mode must be 1");
184 handle
= dlopen(name
, mode
);
185 if (handle
== NULL
) {
186 PyErr_SetString(Dlerror
, dlerror());
189 return newdlobject(handle
);
192 static PyMethodDef dl_methods
[] = {
193 {"open", dl_open
, METH_VARARGS
},
194 {NULL
, NULL
} /* sentinel */
197 /* From socketmodule.c
198 * Convenience routine to export an integer value.
200 * Errors are silently ignored, for better or for worse...
203 insint(PyObject
*d
, char *name
, int value
)
205 PyObject
*v
= PyInt_FromLong((long) value
);
206 if (!v
|| PyDict_SetItemString(d
, name
, v
))
217 /* Initialize object type */
218 Dltype
.ob_type
= &PyType_Type
;
220 /* Create the module and add the functions */
221 m
= Py_InitModule("dl", dl_methods
);
223 /* Add some symbolic constants to the module */
224 d
= PyModule_GetDict(m
);
225 Dlerror
= x
= PyErr_NewException("dl.error", NULL
, NULL
);
226 PyDict_SetItemString(d
, "error", x
);
227 x
= PyInt_FromLong((long)RTLD_LAZY
);
228 PyDict_SetItemString(d
, "RTLD_LAZY", x
);
229 #define INSINT(X) insint(d,#X,X)
252 INSINT(RTLD_NODELETE
);