Last set of CW Pro 5 projects (probably)
[python/dscho.git] / Modules / dlmodule.c
blob18e1458f1c67b7367f45b55d471ab7f296bd9f2f
1 /***********************************************************
2 Copyright (c) 2000, BeOpen.com.
3 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5 All rights reserved.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
11 /* dl module */
13 #include "Python.h"
15 #include <dlfcn.h>
17 #ifndef RTLD_LAZY
18 #define RTLD_LAZY 1
19 #endif
21 typedef void *PyUnivPtr;
22 typedef struct {
23 PyObject_HEAD
24 PyUnivPtr *dl_handle;
25 } dlobject;
27 staticforward PyTypeObject Dltype;
29 static PyObject *Dlerror;
31 static PyObject *
32 newdlobject(PyUnivPtr *handle)
34 dlobject *xp;
35 xp = PyObject_New(dlobject, &Dltype);
36 if (xp == NULL)
37 return NULL;
38 xp->dl_handle = handle;
39 return (PyObject *)xp;
42 static void
43 dl_dealloc(dlobject *xp)
45 if (xp->dl_handle != NULL)
46 dlclose(xp->dl_handle);
47 PyObject_Del(xp);
50 static PyObject *
51 dl_close(dlobject *xp, PyObject *args)
53 if (!PyArg_Parse(args, ""))
54 return NULL;
55 if (xp->dl_handle != NULL) {
56 dlclose(xp->dl_handle);
57 xp->dl_handle = NULL;
59 Py_INCREF(Py_None);
60 return Py_None;
63 static PyObject *
64 dl_sym(dlobject *xp, PyObject *args)
66 char *name;
67 PyUnivPtr *func;
68 if (!PyArg_Parse(args, "s", &name))
69 return NULL;
70 func = dlsym(xp->dl_handle, name);
71 if (func == NULL) {
72 Py_INCREF(Py_None);
73 return Py_None;
75 return PyInt_FromLong((long)func);
78 static PyObject *
79 dl_call(dlobject *xp, PyObject *args)
81 PyObject *name;
82 long (*func)();
83 long alist[10];
84 long res;
85 int i;
86 int n = PyTuple_Size(args);
87 if (n < 1) {
88 PyErr_SetString(PyExc_TypeError, "at least a name is needed");
89 return NULL;
91 name = PyTuple_GetItem(args, 0);
92 if (!PyString_Check(name)) {
93 PyErr_SetString(PyExc_TypeError,
94 "function name must be a string");
95 return NULL;
97 func = dlsym(xp->dl_handle, PyString_AsString(name));
98 if (func == NULL) {
99 PyErr_SetString(PyExc_ValueError, dlerror());
100 return NULL;
102 if (n-1 > 10) {
103 PyErr_SetString(PyExc_TypeError,
104 "too many arguments (max 10)");
105 return NULL;
107 for (i = 1; i < n; i++) {
108 PyObject *v = PyTuple_GetItem(args, i);
109 if (PyInt_Check(v))
110 alist[i-1] = PyInt_AsLong(v);
111 else if (PyString_Check(v))
112 alist[i-1] = (long)PyString_AsString(v);
113 else if (v == Py_None)
114 alist[i-1] = (long) ((char *)NULL);
115 else {
116 PyErr_SetString(PyExc_TypeError,
117 "arguments must be int, string or None");
118 return NULL;
121 for (; i <= 10; i++)
122 alist[i-1] = 0;
123 res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
124 alist[5], alist[6], alist[7], alist[8], alist[9]);
125 return PyInt_FromLong(res);
128 static PyMethodDef dlobject_methods[] = {
129 {"call", (PyCFunction)dl_call, 1 /* varargs */},
130 {"sym", (PyCFunction)dl_sym},
131 {"close", (PyCFunction)dl_close},
132 {NULL, NULL} /* Sentinel */
135 static PyObject *
136 dl_getattr(dlobject *xp, char *name)
138 return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
142 static PyTypeObject Dltype = {
143 PyObject_HEAD_INIT(&PyType_Type)
144 0, /*ob_size*/
145 "dl", /*tp_name*/
146 sizeof(dlobject), /*tp_basicsize*/
147 0, /*tp_itemsize*/
148 /* methods */
149 (destructor)dl_dealloc, /*tp_dealloc*/
150 0, /*tp_print*/
151 (getattrfunc)dl_getattr,/*tp_getattr*/
152 0, /*tp_setattr*/
153 0, /*tp_compare*/
154 0, /*tp_repr*/
155 0, /*tp_as_number*/
156 0, /*tp_as_sequence*/
157 0, /*tp_as_mapping*/
158 0, /*tp_hash*/
161 static PyObject *
162 dl_open(PyObject *self, PyObject *args)
164 char *name;
165 int mode;
166 PyUnivPtr *handle;
167 if (PyArg_Parse(args, "z", &name))
168 mode = RTLD_LAZY;
169 else {
170 PyErr_Clear();
171 if (!PyArg_Parse(args, "(zi)", &name, &mode))
172 return NULL;
173 #ifndef RTLD_NOW
174 if (mode != RTLD_LAZY) {
175 PyErr_SetString(PyExc_ValueError, "mode must be 1");
176 return NULL;
178 #endif
180 handle = dlopen(name, mode);
181 if (handle == NULL) {
182 PyErr_SetString(Dlerror, dlerror());
183 return NULL;
185 return newdlobject(handle);
188 static PyMethodDef dl_methods[] = {
189 {"open", dl_open},
190 {NULL, NULL} /* sentinel */
193 void
194 initdl(void)
196 PyObject *m, *d, *x;
198 if (sizeof(int) != sizeof(long) ||
199 sizeof(long) != sizeof(char *)) {
200 PyErr_SetString(PyExc_SystemError,
201 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
202 return;
205 /* Create the module and add the functions */
206 m = Py_InitModule("dl", dl_methods);
208 /* Add some symbolic constants to the module */
209 d = PyModule_GetDict(m);
210 Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
211 PyDict_SetItemString(d, "error", x);
212 x = PyInt_FromLong((long)RTLD_LAZY);
213 PyDict_SetItemString(d, "RTLD_LAZY", x);
214 #ifdef RTLD_NOW
215 x = PyInt_FromLong((long)RTLD_NOW);
216 PyDict_SetItemString(d, "RTLD_NOW", x);
217 #endif