blob: 6a0a113b61dc47b3a6d2bdf07ebcd77bff9614f4 [file] [log] [blame]
Guido van Rossum34162a11994-05-23 12:37:57 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum34162a11994-05-23 12:37:57 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum34162a11994-05-23 12:37:57 +00009******************************************************************/
10
11/* dl module */
12
Roger E. Masse0e120321996-12-13 20:33:44 +000013#include "Python.h"
Guido van Rossum34162a11994-05-23 12:37:57 +000014
15#include <dlfcn.h>
16
17#ifndef RTLD_LAZY
18#define RTLD_LAZY 1
19#endif
20
Roger E. Masse0e120321996-12-13 20:33:44 +000021typedef ANY *PyUnivPtr;
Guido van Rossum34162a11994-05-23 12:37:57 +000022typedef struct {
Roger E. Masse0e120321996-12-13 20:33:44 +000023 PyObject_HEAD
24 PyUnivPtr *dl_handle;
Guido van Rossum34162a11994-05-23 12:37:57 +000025} dlobject;
26
Roger E. Masse0e120321996-12-13 20:33:44 +000027staticforward PyTypeObject Dltype;
Guido van Rossum34162a11994-05-23 12:37:57 +000028
Roger E. Masse0e120321996-12-13 20:33:44 +000029static PyObject *Dlerror;
Guido van Rossum34162a11994-05-23 12:37:57 +000030
Roger E. Masse0e120321996-12-13 20:33:44 +000031static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000032newdlobject(handle)
Roger E. Masse0e120321996-12-13 20:33:44 +000033 PyUnivPtr *handle;
Guido van Rossum34162a11994-05-23 12:37:57 +000034{
35 dlobject *xp;
Guido van Rossumb18618d2000-05-03 23:44:39 +000036 xp = PyObject_New(dlobject, &Dltype);
Guido van Rossum34162a11994-05-23 12:37:57 +000037 if (xp == NULL)
38 return NULL;
39 xp->dl_handle = handle;
Roger E. Masse0e120321996-12-13 20:33:44 +000040 return (PyObject *)xp;
Guido van Rossum34162a11994-05-23 12:37:57 +000041}
42
43static void
44dl_dealloc(xp)
45 dlobject *xp;
46{
47 if (xp->dl_handle != NULL)
48 dlclose(xp->dl_handle);
Guido van Rossumb18618d2000-05-03 23:44:39 +000049 PyObject_Del(xp);
Guido van Rossum34162a11994-05-23 12:37:57 +000050}
51
Roger E. Masse0e120321996-12-13 20:33:44 +000052static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000053dl_close(xp, args)
54 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000055 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +000056{
Roger E. Masse0e120321996-12-13 20:33:44 +000057 if (!PyArg_Parse(args, ""))
Guido van Rossum34162a11994-05-23 12:37:57 +000058 return NULL;
59 if (xp->dl_handle != NULL) {
60 dlclose(xp->dl_handle);
61 xp->dl_handle = NULL;
62 }
Roger E. Masse0e120321996-12-13 20:33:44 +000063 Py_INCREF(Py_None);
64 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +000065}
66
Roger E. Masse0e120321996-12-13 20:33:44 +000067static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000068dl_sym(xp, args)
69 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000070 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +000071{
72 char *name;
Roger E. Masse0e120321996-12-13 20:33:44 +000073 PyUnivPtr *func;
74 if (!PyArg_Parse(args, "s", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +000075 return NULL;
76 func = dlsym(xp->dl_handle, name);
77 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +000078 Py_INCREF(Py_None);
79 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +000080 }
Roger E. Masse0e120321996-12-13 20:33:44 +000081 return PyInt_FromLong((long)func);
Guido van Rossum34162a11994-05-23 12:37:57 +000082}
83
Roger E. Masse0e120321996-12-13 20:33:44 +000084static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +000085dl_call(xp, args)
86 dlobject *xp;
Roger E. Masse0e120321996-12-13 20:33:44 +000087 PyObject *args; /* (varargs) */
Guido van Rossum34162a11994-05-23 12:37:57 +000088{
Roger E. Masse0e120321996-12-13 20:33:44 +000089 PyObject *name;
Guido van Rossum34162a11994-05-23 12:37:57 +000090 long (*func)();
91 long alist[10];
92 long res;
93 int i;
Roger E. Masse0e120321996-12-13 20:33:44 +000094 int n = PyTuple_Size(args);
Guido van Rossum34162a11994-05-23 12:37:57 +000095 if (n < 1) {
Roger E. Masse0e120321996-12-13 20:33:44 +000096 PyErr_SetString(PyExc_TypeError, "at least a name is needed");
Guido van Rossum34162a11994-05-23 12:37:57 +000097 return NULL;
98 }
Roger E. Masse0e120321996-12-13 20:33:44 +000099 name = PyTuple_GetItem(args, 0);
100 if (!PyString_Check(name)) {
101 PyErr_SetString(PyExc_TypeError,
102 "function name must be a string");
Guido van Rossum34162a11994-05-23 12:37:57 +0000103 return NULL;
104 }
Roger E. Masse0e120321996-12-13 20:33:44 +0000105 func = dlsym(xp->dl_handle, PyString_AsString(name));
Guido van Rossum34162a11994-05-23 12:37:57 +0000106 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000107 PyErr_SetString(PyExc_ValueError, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000108 return NULL;
109 }
110 if (n-1 > 10) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000111 PyErr_SetString(PyExc_TypeError,
112 "too many arguments (max 10)");
Guido van Rossum34162a11994-05-23 12:37:57 +0000113 return NULL;
114 }
115 for (i = 1; i < n; i++) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000116 PyObject *v = PyTuple_GetItem(args, i);
117 if (PyInt_Check(v))
118 alist[i-1] = PyInt_AsLong(v);
119 else if (PyString_Check(v))
120 alist[i-1] = (long)PyString_AsString(v);
121 else if (v == Py_None)
Guido van Rossum34162a11994-05-23 12:37:57 +0000122 alist[i-1] = (long) ((char *)NULL);
123 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000124 PyErr_SetString(PyExc_TypeError,
Guido van Rossum34162a11994-05-23 12:37:57 +0000125 "arguments must be int, string or None");
126 return NULL;
127 }
128 }
129 for (; i <= 10; i++)
130 alist[i-1] = 0;
131 res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
132 alist[5], alist[6], alist[7], alist[8], alist[9]);
Roger E. Masse0e120321996-12-13 20:33:44 +0000133 return PyInt_FromLong(res);
Guido van Rossum34162a11994-05-23 12:37:57 +0000134}
135
Roger E. Masse0e120321996-12-13 20:33:44 +0000136static PyMethodDef dlobject_methods[] = {
137 {"call", (PyCFunction)dl_call, 1 /* varargs */},
138 {"sym", (PyCFunction)dl_sym},
139 {"close", (PyCFunction)dl_close},
140 {NULL, NULL} /* Sentinel */
Guido van Rossum34162a11994-05-23 12:37:57 +0000141};
142
Roger E. Masse0e120321996-12-13 20:33:44 +0000143static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +0000144dl_getattr(xp, name)
145 dlobject *xp;
146 char *name;
147{
Roger E. Masse0e120321996-12-13 20:33:44 +0000148 return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
Guido van Rossum34162a11994-05-23 12:37:57 +0000149}
150
151
Roger E. Masse0e120321996-12-13 20:33:44 +0000152static PyTypeObject Dltype = {
153 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum34162a11994-05-23 12:37:57 +0000154 0, /*ob_size*/
155 "dl", /*tp_name*/
156 sizeof(dlobject), /*tp_basicsize*/
157 0, /*tp_itemsize*/
158 /* methods */
159 (destructor)dl_dealloc, /*tp_dealloc*/
160 0, /*tp_print*/
161 (getattrfunc)dl_getattr,/*tp_getattr*/
162 0, /*tp_setattr*/
163 0, /*tp_compare*/
164 0, /*tp_repr*/
165 0, /*tp_as_number*/
166 0, /*tp_as_sequence*/
167 0, /*tp_as_mapping*/
168 0, /*tp_hash*/
169};
170
Roger E. Masse0e120321996-12-13 20:33:44 +0000171static PyObject *
Guido van Rossum34162a11994-05-23 12:37:57 +0000172dl_open(self, args)
Roger E. Masse0e120321996-12-13 20:33:44 +0000173 PyObject *self;
174 PyObject *args;
Guido van Rossum34162a11994-05-23 12:37:57 +0000175{
176 char *name;
177 int mode;
Roger E. Masse0e120321996-12-13 20:33:44 +0000178 PyUnivPtr *handle;
179 if (PyArg_Parse(args, "z", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +0000180 mode = RTLD_LAZY;
181 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000182 PyErr_Clear();
183 if (!PyArg_Parse(args, "(zi)", &name, &mode))
Guido van Rossum34162a11994-05-23 12:37:57 +0000184 return NULL;
185#ifndef RTLD_NOW
186 if (mode != RTLD_LAZY) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000187 PyErr_SetString(PyExc_ValueError, "mode must be 1");
Guido van Rossum34162a11994-05-23 12:37:57 +0000188 return NULL;
189 }
190#endif
191 }
192 handle = dlopen(name, mode);
193 if (handle == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000194 PyErr_SetString(Dlerror, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000195 return NULL;
196 }
197 return newdlobject(handle);
198}
199
Roger E. Masse0e120321996-12-13 20:33:44 +0000200static PyMethodDef dl_methods[] = {
Guido van Rossum34162a11994-05-23 12:37:57 +0000201 {"open", dl_open},
202 {NULL, NULL} /* sentinel */
203};
204
205void
206initdl()
207{
Roger E. Masse0e120321996-12-13 20:33:44 +0000208 PyObject *m, *d, *x;
Guido van Rossum34162a11994-05-23 12:37:57 +0000209
210 if (sizeof(int) != sizeof(long) ||
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000211 sizeof(long) != sizeof(char *)) {
Guido van Rossume7951971997-12-16 23:58:15 +0000212 PyErr_SetString(PyExc_SystemError,
Guido van Rossum34162a11994-05-23 12:37:57 +0000213 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000214 return;
215 }
Guido van Rossum34162a11994-05-23 12:37:57 +0000216
217 /* Create the module and add the functions */
Roger E. Masse0e120321996-12-13 20:33:44 +0000218 m = Py_InitModule("dl", dl_methods);
Guido van Rossum34162a11994-05-23 12:37:57 +0000219
220 /* Add some symbolic constants to the module */
Roger E. Masse0e120321996-12-13 20:33:44 +0000221 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000222 Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
Roger E. Masse0e120321996-12-13 20:33:44 +0000223 PyDict_SetItemString(d, "error", x);
224 x = PyInt_FromLong((long)RTLD_LAZY);
225 PyDict_SetItemString(d, "RTLD_LAZY", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000226#ifdef RTLD_NOW
Roger E. Masse0e120321996-12-13 20:33:44 +0000227 x = PyInt_FromLong((long)RTLD_NOW);
228 PyDict_SetItemString(d, "RTLD_NOW", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000229#endif
Guido van Rossum34162a11994-05-23 12:37:57 +0000230}