16 typedef void *PyUnivPtr
;
22 static PyTypeObject Dltype
;
24 static PyObject
*Dlerror
;
27 newdlobject(PyUnivPtr
*handle
)
30 xp
= PyObject_New(dlobject
, &Dltype
);
33 xp
->dl_handle
= handle
;
34 return (PyObject
*)xp
;
38 dl_dealloc(dlobject
*xp
)
40 if (xp
->dl_handle
!= NULL
)
41 dlclose(xp
->dl_handle
);
46 dl_close(dlobject
*xp
)
48 if (xp
->dl_handle
!= NULL
) {
49 dlclose(xp
->dl_handle
);
57 dl_sym(dlobject
*xp
, PyObject
*args
)
61 if (PyString_Check(args
)) {
62 name
= PyString_AS_STRING(args
);
64 PyErr_Format(PyExc_TypeError
, "expected string, found %.200s",
65 Py_TYPE(args
)->tp_name
);
68 func
= dlsym(xp
->dl_handle
, name
);
73 return PyInt_FromLong((long)func
);
77 dl_call(dlobject
*xp
, PyObject
*args
)
80 long (*func
)(long, long, long, long, long,
81 long, long, long, long, long);
85 Py_ssize_t n
= PyTuple_Size(args
);
87 PyErr_SetString(PyExc_TypeError
, "at least a name is needed");
90 name
= PyTuple_GetItem(args
, 0);
91 if (!PyString_Check(name
)) {
92 PyErr_SetString(PyExc_TypeError
,
93 "function name must be a string");
96 func
= (long (*)(long, long, long, long, long,
97 long, long, long, long, long))
98 dlsym(xp
->dl_handle
, PyString_AsString(name
));
100 PyErr_SetString(PyExc_ValueError
, dlerror());
104 PyErr_SetString(PyExc_TypeError
,
105 "too many arguments (max 10)");
108 for (i
= 1; i
< n
; i
++) {
109 PyObject
*v
= PyTuple_GetItem(args
, i
);
111 alist
[i
-1] = PyInt_AsLong(v
);
112 else if (PyString_Check(v
))
113 alist
[i
-1] = (long)PyString_AsString(v
);
114 else if (v
== Py_None
)
115 alist
[i
-1] = (long) ((char *)NULL
);
117 PyErr_SetString(PyExc_TypeError
,
118 "arguments must be int, string or None");
124 res
= (*func
)(alist
[0], alist
[1], alist
[2], alist
[3], alist
[4],
125 alist
[5], alist
[6], alist
[7], alist
[8], alist
[9]);
126 return PyInt_FromLong(res
);
129 static PyMethodDef dlobject_methods
[] = {
130 {"call", (PyCFunction
)dl_call
, METH_VARARGS
},
131 {"sym", (PyCFunction
)dl_sym
, METH_O
},
132 {"close", (PyCFunction
)dl_close
, METH_NOARGS
},
133 {NULL
, NULL
} /* Sentinel */
137 dl_getattr(dlobject
*xp
, char *name
)
139 return Py_FindMethod(dlobject_methods
, (PyObject
*)xp
, name
);
143 static PyTypeObject Dltype
= {
144 PyVarObject_HEAD_INIT(NULL
, 0)
146 sizeof(dlobject
), /*tp_basicsize*/
149 (destructor
)dl_dealloc
, /*tp_dealloc*/
151 (getattrfunc
)dl_getattr
,/*tp_getattr*/
156 0, /*tp_as_sequence*/
162 dl_open(PyObject
*self
, PyObject
*args
)
167 if (sizeof(int) != sizeof(long) ||
168 sizeof(long) != sizeof(char *)) {
169 PyErr_SetString(PyExc_SystemError
,
170 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
174 if (PyArg_ParseTuple(args
, "z:open", &name
))
178 if (!PyArg_ParseTuple(args
, "zi:open", &name
, &mode
))
181 if (mode
!= RTLD_LAZY
) {
182 PyErr_SetString(PyExc_ValueError
, "mode must be 1");
187 handle
= dlopen(name
, mode
);
188 if (handle
== NULL
) {
189 char *errmsg
= dlerror();
191 errmsg
= "dlopen() error";
192 PyErr_SetString(Dlerror
, errmsg
);
196 /* Under OpenVMS dlopen doesn't do any check, just save the name
197 * for later use, so we have to check if the file is readable,
198 * the name can be a logical or a file from SYS$SHARE.
200 if (access(name
, R_OK
)) {
201 char fname
[strlen(name
) + 20];
202 strcpy(fname
, "SYS$SHARE:");
204 strcat(fname
, ".EXE");
205 if (access(fname
, R_OK
)) {
207 PyErr_SetString(Dlerror
,
208 "File not found or protection violation");
213 return newdlobject(handle
);
216 static PyMethodDef dl_methods
[] = {
217 {"open", dl_open
, METH_VARARGS
},
218 {NULL
, NULL
} /* sentinel */
221 /* From socketmodule.c
222 * Convenience routine to export an integer value.
224 * Errors are silently ignored, for better or for worse...
227 insint(PyObject
*d
, char *name
, int value
)
229 PyObject
*v
= PyInt_FromLong((long) value
);
230 if (!v
|| PyDict_SetItemString(d
, name
, v
))
241 if (PyErr_WarnPy3k("the dl module has been removed in "
242 "Python 3.0; use the ctypes module instead", 2) < 0)
245 /* Initialize object type */
246 Py_TYPE(&Dltype
) = &PyType_Type
;
248 /* Create the module and add the functions */
249 m
= Py_InitModule("dl", dl_methods
);
253 /* Add some symbolic constants to the module */
254 d
= PyModule_GetDict(m
);
255 Dlerror
= x
= PyErr_NewException("dl.error", NULL
, NULL
);
256 PyDict_SetItemString(d
, "error", x
);
257 x
= PyInt_FromLong((long)RTLD_LAZY
);
258 PyDict_SetItemString(d
, "RTLD_LAZY", x
);
259 #define INSINT(X) insint(d,#X,X)
282 INSINT(RTLD_NODELETE
);