blob: 169f49c413b93ec1064013f993d4698e0557f272 [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 *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000032newdlobject(PyUnivPtr *handle)
Guido van Rossum34162a11994-05-23 12:37:57 +000033{
34 dlobject *xp;
Guido van Rossumb18618d2000-05-03 23:44:39 +000035 xp = PyObject_New(dlobject, &Dltype);
Guido van Rossum34162a11994-05-23 12:37:57 +000036 if (xp == NULL)
37 return NULL;
38 xp->dl_handle = handle;
Roger E. Masse0e120321996-12-13 20:33:44 +000039 return (PyObject *)xp;
Guido van Rossum34162a11994-05-23 12:37:57 +000040}
41
42static void
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000043dl_dealloc(dlobject *xp)
Guido van Rossum34162a11994-05-23 12:37:57 +000044{
45 if (xp->dl_handle != NULL)
46 dlclose(xp->dl_handle);
Guido van Rossumb18618d2000-05-03 23:44:39 +000047 PyObject_Del(xp);
Guido van Rossum34162a11994-05-23 12:37:57 +000048}
49
Roger E. Masse0e120321996-12-13 20:33:44 +000050static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000051dl_close(dlobject *xp, PyObject *args)
Guido van Rossum34162a11994-05-23 12:37:57 +000052{
Roger E. Masse0e120321996-12-13 20:33:44 +000053 if (!PyArg_Parse(args, ""))
Guido van Rossum34162a11994-05-23 12:37:57 +000054 return NULL;
55 if (xp->dl_handle != NULL) {
56 dlclose(xp->dl_handle);
57 xp->dl_handle = NULL;
58 }
Roger E. Masse0e120321996-12-13 20:33:44 +000059 Py_INCREF(Py_None);
60 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +000061}
62
Roger E. Masse0e120321996-12-13 20:33:44 +000063static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000064dl_sym(dlobject *xp, PyObject *args)
Guido van Rossum34162a11994-05-23 12:37:57 +000065{
66 char *name;
Roger E. Masse0e120321996-12-13 20:33:44 +000067 PyUnivPtr *func;
68 if (!PyArg_Parse(args, "s", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +000069 return NULL;
70 func = dlsym(xp->dl_handle, name);
71 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +000072 Py_INCREF(Py_None);
73 return Py_None;
Guido van Rossum34162a11994-05-23 12:37:57 +000074 }
Roger E. Masse0e120321996-12-13 20:33:44 +000075 return PyInt_FromLong((long)func);
Guido van Rossum34162a11994-05-23 12:37:57 +000076}
77
Roger E. Masse0e120321996-12-13 20:33:44 +000078static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000079dl_call(dlobject *xp, PyObject *args)
Guido van Rossum34162a11994-05-23 12:37:57 +000080{
Roger E. Masse0e120321996-12-13 20:33:44 +000081 PyObject *name;
Guido van Rossum34162a11994-05-23 12:37:57 +000082 long (*func)();
83 long alist[10];
84 long res;
85 int i;
Roger E. Masse0e120321996-12-13 20:33:44 +000086 int n = PyTuple_Size(args);
Guido van Rossum34162a11994-05-23 12:37:57 +000087 if (n < 1) {
Roger E. Masse0e120321996-12-13 20:33:44 +000088 PyErr_SetString(PyExc_TypeError, "at least a name is needed");
Guido van Rossum34162a11994-05-23 12:37:57 +000089 return NULL;
90 }
Roger E. Masse0e120321996-12-13 20:33:44 +000091 name = PyTuple_GetItem(args, 0);
92 if (!PyString_Check(name)) {
93 PyErr_SetString(PyExc_TypeError,
94 "function name must be a string");
Guido van Rossum34162a11994-05-23 12:37:57 +000095 return NULL;
96 }
Roger E. Masse0e120321996-12-13 20:33:44 +000097 func = dlsym(xp->dl_handle, PyString_AsString(name));
Guido van Rossum34162a11994-05-23 12:37:57 +000098 if (func == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +000099 PyErr_SetString(PyExc_ValueError, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000100 return NULL;
101 }
102 if (n-1 > 10) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000103 PyErr_SetString(PyExc_TypeError,
104 "too many arguments (max 10)");
Guido van Rossum34162a11994-05-23 12:37:57 +0000105 return NULL;
106 }
107 for (i = 1; i < n; i++) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000108 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)
Guido van Rossum34162a11994-05-23 12:37:57 +0000114 alist[i-1] = (long) ((char *)NULL);
115 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000116 PyErr_SetString(PyExc_TypeError,
Guido van Rossum34162a11994-05-23 12:37:57 +0000117 "arguments must be int, string or None");
118 return NULL;
119 }
120 }
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]);
Roger E. Masse0e120321996-12-13 20:33:44 +0000125 return PyInt_FromLong(res);
Guido van Rossum34162a11994-05-23 12:37:57 +0000126}
127
Roger E. Masse0e120321996-12-13 20:33:44 +0000128static PyMethodDef dlobject_methods[] = {
129 {"call", (PyCFunction)dl_call, 1 /* varargs */},
130 {"sym", (PyCFunction)dl_sym},
131 {"close", (PyCFunction)dl_close},
132 {NULL, NULL} /* Sentinel */
Guido van Rossum34162a11994-05-23 12:37:57 +0000133};
134
Roger E. Masse0e120321996-12-13 20:33:44 +0000135static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000136dl_getattr(dlobject *xp, char *name)
Guido van Rossum34162a11994-05-23 12:37:57 +0000137{
Roger E. Masse0e120321996-12-13 20:33:44 +0000138 return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
Guido van Rossum34162a11994-05-23 12:37:57 +0000139}
140
141
Roger E. Masse0e120321996-12-13 20:33:44 +0000142static PyTypeObject Dltype = {
143 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum34162a11994-05-23 12:37:57 +0000144 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*/
159};
160
Roger E. Masse0e120321996-12-13 20:33:44 +0000161static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000162dl_open(PyObject *self, PyObject *args)
Guido van Rossum34162a11994-05-23 12:37:57 +0000163{
164 char *name;
165 int mode;
Roger E. Masse0e120321996-12-13 20:33:44 +0000166 PyUnivPtr *handle;
167 if (PyArg_Parse(args, "z", &name))
Guido van Rossum34162a11994-05-23 12:37:57 +0000168 mode = RTLD_LAZY;
169 else {
Roger E. Masse0e120321996-12-13 20:33:44 +0000170 PyErr_Clear();
171 if (!PyArg_Parse(args, "(zi)", &name, &mode))
Guido van Rossum34162a11994-05-23 12:37:57 +0000172 return NULL;
173#ifndef RTLD_NOW
174 if (mode != RTLD_LAZY) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000175 PyErr_SetString(PyExc_ValueError, "mode must be 1");
Guido van Rossum34162a11994-05-23 12:37:57 +0000176 return NULL;
177 }
178#endif
179 }
180 handle = dlopen(name, mode);
181 if (handle == NULL) {
Roger E. Masse0e120321996-12-13 20:33:44 +0000182 PyErr_SetString(Dlerror, dlerror());
Guido van Rossum34162a11994-05-23 12:37:57 +0000183 return NULL;
184 }
185 return newdlobject(handle);
186}
187
Roger E. Masse0e120321996-12-13 20:33:44 +0000188static PyMethodDef dl_methods[] = {
Guido van Rossum34162a11994-05-23 12:37:57 +0000189 {"open", dl_open},
190 {NULL, NULL} /* sentinel */
191};
192
193void
194initdl()
195{
Roger E. Masse0e120321996-12-13 20:33:44 +0000196 PyObject *m, *d, *x;
Guido van Rossum34162a11994-05-23 12:37:57 +0000197
198 if (sizeof(int) != sizeof(long) ||
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000199 sizeof(long) != sizeof(char *)) {
Guido van Rossume7951971997-12-16 23:58:15 +0000200 PyErr_SetString(PyExc_SystemError,
Guido van Rossum34162a11994-05-23 12:37:57 +0000201 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000202 return;
203 }
Guido van Rossum34162a11994-05-23 12:37:57 +0000204
205 /* Create the module and add the functions */
Roger E. Masse0e120321996-12-13 20:33:44 +0000206 m = Py_InitModule("dl", dl_methods);
Guido van Rossum34162a11994-05-23 12:37:57 +0000207
208 /* Add some symbolic constants to the module */
Roger E. Masse0e120321996-12-13 20:33:44 +0000209 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000210 Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
Roger E. Masse0e120321996-12-13 20:33:44 +0000211 PyDict_SetItemString(d, "error", x);
212 x = PyInt_FromLong((long)RTLD_LAZY);
213 PyDict_SetItemString(d, "RTLD_LAZY", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000214#ifdef RTLD_NOW
Roger E. Masse0e120321996-12-13 20:33:44 +0000215 x = PyInt_FromLong((long)RTLD_NOW);
216 PyDict_SetItemString(d, "RTLD_NOW", x);
Guido van Rossum34162a11994-05-23 12:37:57 +0000217#endif
Guido van Rossum34162a11994-05-23 12:37:57 +0000218}