blob: ae3482ff6aae4a862e8d4bb8516a5cf41d15ea2f [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
34#include "allobjects.h"
35#include "modsupport.h"
36
37#include <dlfcn.h>
38
39#ifndef RTLD_LAZY
40#define RTLD_LAZY 1
41#endif
42
43typedef struct {
44 OB_HEAD
45 ANY *dl_handle;
46} dlobject;
47
48staticforward typeobject Dltype;
49
50static object *Dlerror;
51
52static object *
53newdlobject(handle)
54 ANY *handle;
55{
56 dlobject *xp;
57 xp = NEWOBJ(dlobject, &Dltype);
58 if (xp == NULL)
59 return NULL;
60 xp->dl_handle = handle;
61 return (object *)xp;
62}
63
64static void
65dl_dealloc(xp)
66 dlobject *xp;
67{
68 if (xp->dl_handle != NULL)
69 dlclose(xp->dl_handle);
70 DEL(xp);
71}
72
73static object *
74dl_close(xp, args)
75 dlobject *xp;
76 object *args;
77{
78 if (!getargs(args, ""))
79 return NULL;
80 if (xp->dl_handle != NULL) {
81 dlclose(xp->dl_handle);
82 xp->dl_handle = NULL;
83 }
84 INCREF(None);
85 return None;
86}
87
88static object *
89dl_sym(xp, args)
90 dlobject *xp;
91 object *args;
92{
93 char *name;
94 ANY *func;
95 if (!getargs(args, "s", &name))
96 return NULL;
97 func = dlsym(xp->dl_handle, name);
98 if (func == NULL) {
99 INCREF(None);
100 return None;
101 }
102 return newintobject((long)func);
103}
104
105static object *
106dl_call(xp, args)
107 dlobject *xp;
108 object *args; /* (varargs) */
109{
110 object *name;
111 long (*func)();
112 long alist[10];
113 long res;
114 int i;
115 int n = gettuplesize(args);
116 if (n < 1) {
117 err_setstr(TypeError, "at least a name is needed");
118 return NULL;
119 }
120 name = gettupleitem(args, 0);
121 if (!is_stringobject(name)) {
122 err_setstr(TypeError, "function name must be a string");
123 return NULL;
124 }
125 func = dlsym(xp->dl_handle, getstringvalue(name));
126 if (func == NULL) {
127 err_setstr(ValueError, dlerror());
128 return NULL;
129 }
130 if (n-1 > 10) {
131 err_setstr(TypeError, "too many arguments (max 10)");
132 return NULL;
133 }
134 for (i = 1; i < n; i++) {
135 object *v = gettupleitem(args, i);
136 if (is_intobject(v))
137 alist[i-1] = getintvalue(v);
138 else if (is_stringobject(v))
139 alist[i-1] = (long)getstringvalue(v);
140 else if (v == None)
141 alist[i-1] = (long) ((char *)NULL);
142 else {
143 err_setstr(TypeError,
144 "arguments must be int, string or None");
145 return NULL;
146 }
147 }
148 for (; i <= 10; i++)
149 alist[i-1] = 0;
150 res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
151 alist[5], alist[6], alist[7], alist[8], alist[9]);
152 return newintobject(res);
153}
154
155static struct methodlist dlobject_methods[] = {
156 {"call", (method)dl_call, 1 /* varargs */},
157 {"sym", (method)dl_sym},
158 {"close", (method)dl_close},
159 {NULL, NULL} /* Sentinel */
160};
161
162static object *
163dl_getattr(xp, name)
164 dlobject *xp;
165 char *name;
166{
167 return findmethod(dlobject_methods, (object *)xp, name);
168}
169
170
171static typeobject Dltype = {
172 OB_HEAD_INIT(&Typetype)
173 0, /*ob_size*/
174 "dl", /*tp_name*/
175 sizeof(dlobject), /*tp_basicsize*/
176 0, /*tp_itemsize*/
177 /* methods */
178 (destructor)dl_dealloc, /*tp_dealloc*/
179 0, /*tp_print*/
180 (getattrfunc)dl_getattr,/*tp_getattr*/
181 0, /*tp_setattr*/
182 0, /*tp_compare*/
183 0, /*tp_repr*/
184 0, /*tp_as_number*/
185 0, /*tp_as_sequence*/
186 0, /*tp_as_mapping*/
187 0, /*tp_hash*/
188};
189
190static object *
191dl_open(self, args)
192 object *self;
193 object *args;
194{
195 char *name;
196 int mode;
197 ANY *handle;
198 if (getargs(args, "z", &name))
199 mode = RTLD_LAZY;
200 else {
201 err_clear();
202 if (!getargs(args, "(zi)", &name, &mode))
203 return NULL;
204#ifndef RTLD_NOW
205 if (mode != RTLD_LAZY) {
206 err_setstr(ValueError, "mode must be 1");
207 return NULL;
208 }
209#endif
210 }
211 handle = dlopen(name, mode);
212 if (handle == NULL) {
213 err_setstr(Dlerror, dlerror());
214 return NULL;
215 }
216 return newdlobject(handle);
217}
218
219static struct methodlist dl_methods[] = {
220 {"open", dl_open},
221 {NULL, NULL} /* sentinel */
222};
223
224void
225initdl()
226{
227 object *m, *d, *x;
228
229 if (sizeof(int) != sizeof(long) ||
230 sizeof(long) != sizeof(char *))
231 fatal(
232 "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
233
234 /* Create the module and add the functions */
235 m = initmodule("dl", dl_methods);
236
237 /* Add some symbolic constants to the module */
238 d = getmoduledict(m);
239 Dlerror = x = newstringobject("dl.error");
240 dictinsert(d, "error", x);
241 x = newintobject((long)RTLD_LAZY);
242 dictinsert(d, "RTLD_LAZY", x);
243#ifdef RTLD_NOW
244 x = newintobject((long)RTLD_NOW);
245 dictinsert(d, "RTLD_NOW", x);
246#endif
247
248 /* Check for errors */
249 if (err_occurred())
250 fatal("can't initialize module dl");
251}