blob: d94665887382b10d177c5964d22f592d76b00389 [file] [log] [blame]
Guido van Rossum34162a11994-05-23 12:37:57 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum34162a11994-05-23 12:37:57 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum34162a11994-05-23 12:37:57 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum34162a11994-05-23 12:37:57 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum34162a11994-05-23 12:37:57 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum34162a11994-05-23 12:37:57 +000029
30******************************************************************/
31
32/* dl module */
33
Roger E. Masse0e120321996-12-13 20:33:44 +000034#include "Python.h"
Guido van Rossum34162a11994-05-23 12:37:57 +000035
36#include <dlfcn.h>
37
38#ifndef RTLD_LAZY
39#define RTLD_LAZY 1
40#endif
41
Roger E. Masse0e120321996-12-13 20:33:44 +000042typedef ANY *PyUnivPtr;
Guido van Rossum34162a11994-05-23 12:37:57 +000043typedef struct {
Roger E. Masse0e120321996-12-13 20:33:44 +000044 PyObject_HEAD
45 PyUnivPtr *dl_handle;
Guido van Rossum34162a11994-05-23 12:37:57 +000046} dlobject;
47
Roger E. Masse0e120321996-12-13 20:33:44 +000048staticforward PyTypeObject Dltype;
Guido van Rossum34162a11994-05-23 12:37:57 +000049
Roger E. Masse0e120321996-12-13 20:33:44 +000050static PyObject *Dlerror;
Guido van Rossum34162a11994-05-23 12:37:57 +000051
Roger E. Masse0e120321996-12-13 20:33:44 +000052static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000053newdlobject(handle)
Roger E. Masse0e120321996-12-13 20:33:44 +000054 PyUnivPtr *handle;
Guido van Rossum34162a11994-05-23 12:37:57 +000055{
56 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000057 xp = PyObject_NEW(dlobject, &Dltype);
Guido van Rossum34162a11994-05-23 12:37:57 +000058 if (xp == NULL)
59 return NULL;
60 xp->dl_handle = handle;
Roger E. Masse0e120321996-12-13 20:33:44 +000061 return (PyObject *)xp;
Guido van Rossum34162a11994-05-23 12:37:57 +000062}
63
64static void
65dl_dealloc(xp)
66 dlobject *xp;
67{
68 if (xp->dl_handle != NULL)
69 dlclose(xp->dl_handle);
Roger E. Masse0e120321996-12-13 20:33:44 +000070 PyMem_DEL(xp);
Guido van Rossum34162a11994-05-23 12:37:57 +000071}
72
Roger E. Masse0e120321996-12-13 20:33:44 +000073static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000074dl_close(xp, args)
75 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000076 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +000077{
Roger E. Masse0e120321996-12-13 20:33:44 +000078 if (!PyArg_Parse(args, ""))
Guido van Rossum34162a11994-05-23 12:37:57 +000079 return NULL;
80 if (xp->dl_handle != NULL) {
81 dlclose(xp->dl_handle);
82 xp->dl_handle = NULL;
83 }
Roger E. Masse0e120321996-12-13 20:33:44 +000084 Py_INCREF(Py_None);
85 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +000086}
87
Roger E. Masse0e120321996-12-13 20:33:44 +000088static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000089dl_sym(xp, args)
90 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000091 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +000092{
93 char *name;
Roger E. Masse0e120321996-12-13 20:33:44 +000094 PyUnivPtr *func;
95 if (!PyArg_Parse(args, "s", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +000096 return NULL;
97 func = dlsym(xp->dl_handle, name);
98 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +000099 Py_INCREF(Py_None);
100 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +0000101 }
Roger E. Masse0e120321996-12-13 20:33:44 +0000102 return PyInt_FromLong((long)func);
Guido van Rossum34162a11994-05-23 12:37:57 +0000103}
104
Roger E. Masse0e120321996-12-13 20:33:44 +0000105static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +0000106dl_call(xp, args)
107 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +0000108 PyObject *args; /* (varargs) */
Guido van Rossum34162a11994-05-23 12:37:57 +0000109{
Roger E. Masse0e120321996-12-13 20:33:44 +0000110 PyObject *name;
Guido van Rossum34162a11994-05-23 12:37:57 +0000111 long (*func)();
112 long alist[10];
113 long res;
114 int i;
Roger E. Masse0e120321996-12-13 20:33:44 +0000115 int n = PyTuple_Size(args);
Guido van Rossum34162a11994-05-23 12:37:57 +0000116 if (n < 1) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000117 PyErr_SetString(PyExc_TypeError, "at least a name is needed");
Guido van Rossum34162a11994-05-23 12:37:57 +0000118 return NULL;
119 }
Roger E. Masse0e120321996-12-13 20:33:44 +0000120 name = PyTuple_GetItem(args, 0);
121 if (!PyString_Check(name)) {
122 PyErr_SetString(PyExc_TypeError,
123 "function name must be a string");
Guido van Rossum34162a11994-05-23 12:37:57 +0000124 return NULL;
125 }
Roger E. Masse0e120321996-12-13 20:33:44 +0000126 func = dlsym(xp->dl_handle, PyString_AsString(name));
Guido van Rossum34162a11994-05-23 12:37:57 +0000127 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000128 PyErr_SetString(PyExc_ValueError, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000129 return NULL;
130 }
131 if (n-1 > 10) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000132 PyErr_SetString(PyExc_TypeError,
133 "too many arguments (max 10)");
Guido van Rossum34162a11994-05-23 12:37:57 +0000134 return NULL;
135 }
136 for (i = 1; i < n; i++) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000137 PyObject *v = PyTuple_GetItem(args, i);
138 if (PyInt_Check(v))
139 alist[i-1] = PyInt_AsLong(v);
140 else if (PyString_Check(v))
141 alist[i-1] = (long)PyString_AsString(v);
142 else if (v == Py_None)
Guido van Rossum34162a11994-05-23 12:37:57 +0000143 alist[i-1] = (long) ((char *)NULL);
144 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000145 PyErr_SetString(PyExc_TypeError,
Guido van Rossum34162a11994-05-23 12:37:57 +0000146 "arguments must be int, string or None");
147 return NULL;
148 }
149 }
150 for (; i <= 10; i++)
151 alist[i-1] = 0;
152 res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
153 alist[5], alist[6], alist[7], alist[8], alist[9]);
Roger E. Masse0e120321996-12-13 20:33:44 +0000154 return PyInt_FromLong(res);
Guido van Rossum34162a11994-05-23 12:37:57 +0000155}
156
Roger E. Masse0e120321996-12-13 20:33:44 +0000157static PyMethodDef dlobject_methods[] = {
158 {"call", (PyCFunction)dl_call, 1 /* varargs */},
159 {"sym", (PyCFunction)dl_sym},
160 {"close", (PyCFunction)dl_close},
161 {NULL, NULL} /* Sentinel */
Guido van Rossum34162a11994-05-23 12:37:57 +0000162};
163
Roger E. Masse0e120321996-12-13 20:33:44 +0000164static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +0000165dl_getattr(xp, name)
166 dlobject *xp;
167 char *name;
168{
Roger E. Masse0e120321996-12-13 20:33:44 +0000169 return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
Guido van Rossum34162a11994-05-23 12:37:57 +0000170}
171
172
Roger E. Masse0e120321996-12-13 20:33:44 +0000173static PyTypeObject Dltype = {
174 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum34162a11994-05-23 12:37:57 +0000175 0, /*ob_size*/
176 "dl", /*tp_name*/
177 sizeof(dlobject), /*tp_basicsize*/
178 0, /*tp_itemsize*/
179 /* methods */
180 (destructor)dl_dealloc, /*tp_dealloc*/
181 0, /*tp_print*/
182 (getattrfunc)dl_getattr,/*tp_getattr*/
183 0, /*tp_setattr*/
184 0, /*tp_compare*/
185 0, /*tp_repr*/
186 0, /*tp_as_number*/
187 0, /*tp_as_sequence*/
188 0, /*tp_as_mapping*/
189 0, /*tp_hash*/
190};
191
Roger E. Masse0e120321996-12-13 20:33:44 +0000192static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +0000193dl_open(self, args)
Roger E. Masse0e120321996-12-13 20:33:44 +0000194 PyObject *self;
195 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +0000196{
197 char *name;
198 int mode;
Roger E. Masse0e120321996-12-13 20:33:44 +0000199 PyUnivPtr *handle;
200 if (PyArg_Parse(args, "z", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +0000201 mode = RTLD_LAZY;
202 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000203 PyErr_Clear();
204 if (!PyArg_Parse(args, "(zi)", &name, &mode))
Guido van Rossum34162a11994-05-23 12:37:57 +0000205 return NULL;
206#ifndef RTLD_NOW
207 if (mode != RTLD_LAZY) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000208 PyErr_SetString(PyExc_ValueError, "mode must be 1");
Guido van Rossum34162a11994-05-23 12:37:57 +0000209 return NULL;
210 }
211#endif
212 }
213 handle = dlopen(name, mode);
214 if (handle == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000215 PyErr_SetString(Dlerror, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000216 return NULL;
217 }
218 return newdlobject(handle);
219}
220
Roger E. Masse0e120321996-12-13 20:33:44 +0000221static PyMethodDef dl_methods[] = {
Guido van Rossum34162a11994-05-23 12:37:57 +0000222 {"open", dl_open},
223 {NULL, NULL} /* sentinel */
224};
225
226void
227initdl()
228{
Roger E. Masse0e120321996-12-13 20:33:44 +0000229 PyObject *m, *d, *x;
Guido van Rossum34162a11994-05-23 12:37:57 +0000230
231 if (sizeof(int) != sizeof(long) ||
232 sizeof(long) != sizeof(char *))
Roger E. Masse0e120321996-12-13 20:33:44 +0000233 Py_FatalError(
Guido van Rossum34162a11994-05-23 12:37:57 +0000234 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
235
236 /* Create the module and add the functions */
Roger E. Masse0e120321996-12-13 20:33:44 +0000237 m = Py_InitModule("dl", dl_methods);
Guido van Rossum34162a11994-05-23 12:37:57 +0000238
239 /* Add some symbolic constants to the module */
Roger E. Masse0e120321996-12-13 20:33:44 +0000240 d = PyModule_GetDict(m);
241 Dlerror = x = PyString_FromString("dl.error");
242 PyDict_SetItemString(d, "error", x);
243 x = PyInt_FromLong((long)RTLD_LAZY);
244 PyDict_SetItemString(d, "RTLD_LAZY", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000245#ifdef RTLD_NOW
Roger E. Masse0e120321996-12-13 20:33:44 +0000246 x = PyInt_FromLong((long)RTLD_NOW);
247 PyDict_SetItemString(d, "RTLD_NOW", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000248#endif
249
250 /* Check for errors */
Roger E. Masse0e120321996-12-13 20:33:44 +0000251 if (PyErr_Occurred())
252 Py_FatalError("can't initialize module dl");
Guido van Rossum34162a11994-05-23 12:37:57 +0000253}