| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 1 | /*********************************************************** | 
| Guido van Rossum | 524b588 | 1995-01-04 19:10:35 +0000 | [diff] [blame] | 2 | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
 | 3 | The Netherlands. | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 4 |  | 
 | 5 |                         All Rights Reserved | 
 | 6 |  | 
| Guido van Rossum | d266eb4 | 1996-10-25 14:44:06 +0000 | [diff] [blame] | 7 | Permission to use, copy, modify, and distribute this software and its | 
 | 8 | documentation for any purpose and without fee is hereby granted, | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 9 | provided that the above copyright notice appear in all copies and that | 
| Guido van Rossum | d266eb4 | 1996-10-25 14:44:06 +0000 | [diff] [blame] | 10 | both that copyright notice and this permission notice appear in | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 11 | supporting documentation, and that the names of Stichting Mathematisch | 
| Guido van Rossum | d266eb4 | 1996-10-25 14:44:06 +0000 | [diff] [blame] | 12 | Centrum or CWI or Corporation for National Research Initiatives or | 
 | 13 | CNRI not be used in advertising or publicity pertaining to | 
 | 14 | distribution of the software without specific, written prior | 
 | 15 | permission. | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 16 |  | 
| Guido van Rossum | d266eb4 | 1996-10-25 14:44:06 +0000 | [diff] [blame] | 17 | While CWI is the initial source for this software, a modified version | 
 | 18 | is made available by the Corporation for National Research Initiatives | 
 | 19 | (CNRI) at the Internet address ftp://ftp.python.org. | 
 | 20 |  | 
 | 21 | STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH | 
 | 22 | REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | 
 | 23 | MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH | 
 | 24 | CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | 
 | 25 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
 | 26 | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 
 | 27 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 
 | 28 | PERFORMANCE OF THIS SOFTWARE. | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 29 |  | 
 | 30 | ******************************************************************/ | 
 | 31 |  | 
 | 32 | /* dl module */ | 
 | 33 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 34 | #include "Python.h" | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 35 |  | 
 | 36 | #include <dlfcn.h> | 
 | 37 |  | 
 | 38 | #ifndef RTLD_LAZY | 
 | 39 | #define RTLD_LAZY 1 | 
 | 40 | #endif | 
 | 41 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 42 | typedef ANY *PyUnivPtr; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 43 | typedef struct { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 44 | 	PyObject_HEAD | 
 | 45 | 	PyUnivPtr *dl_handle; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 46 | } dlobject; | 
 | 47 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 48 | staticforward PyTypeObject Dltype; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 49 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 50 | static PyObject *Dlerror; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 51 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 52 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 53 | newdlobject(handle) | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 54 | 	PyUnivPtr *handle; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 55 | { | 
 | 56 | 	dlobject *xp; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 57 | 	xp = PyObject_NEW(dlobject, &Dltype); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 58 | 	if (xp == NULL) | 
 | 59 | 		return NULL; | 
 | 60 | 	xp->dl_handle = handle; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 61 | 	return (PyObject *)xp; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 62 | } | 
 | 63 |  | 
 | 64 | static void | 
 | 65 | dl_dealloc(xp) | 
 | 66 | 	dlobject *xp; | 
 | 67 | { | 
 | 68 | 	if (xp->dl_handle != NULL) | 
 | 69 | 		dlclose(xp->dl_handle); | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 70 | 	PyMem_DEL(xp); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 71 | } | 
 | 72 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 73 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 74 | dl_close(xp, args) | 
 | 75 | 	dlobject *xp; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 76 | 	PyObject *args; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 77 | { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 78 | 	if (!PyArg_Parse(args, "")) | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 79 | 		return NULL; | 
 | 80 | 	if (xp->dl_handle != NULL) { | 
 | 81 | 		dlclose(xp->dl_handle); | 
 | 82 | 		xp->dl_handle = NULL; | 
 | 83 | 	} | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 84 | 	Py_INCREF(Py_None); | 
 | 85 | 	return Py_None; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 86 | } | 
 | 87 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 88 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 89 | dl_sym(xp, args) | 
 | 90 | 	dlobject *xp; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 91 | 	PyObject *args; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 92 | { | 
 | 93 | 	char *name; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 94 | 	PyUnivPtr *func; | 
 | 95 | 	if (!PyArg_Parse(args, "s", &name)) | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 96 | 		return NULL; | 
 | 97 | 	func = dlsym(xp->dl_handle, name); | 
 | 98 | 	if (func == NULL) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 99 | 		Py_INCREF(Py_None); | 
 | 100 | 		return Py_None; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 101 | 	} | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 102 | 	return PyInt_FromLong((long)func); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 103 | } | 
 | 104 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 105 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 106 | dl_call(xp, args) | 
 | 107 | 	dlobject *xp; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 108 | 	PyObject *args; /* (varargs) */ | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 109 | { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 110 | 	PyObject *name; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 111 | 	long (*func)(); | 
 | 112 | 	long alist[10]; | 
 | 113 | 	long res; | 
 | 114 | 	int i; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 115 | 	int n = PyTuple_Size(args); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 116 | 	if (n < 1) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 117 | 		PyErr_SetString(PyExc_TypeError, "at least a name is needed"); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 118 | 		return NULL; | 
 | 119 | 	} | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 120 | 	name = PyTuple_GetItem(args, 0); | 
 | 121 | 	if (!PyString_Check(name)) { | 
 | 122 | 		PyErr_SetString(PyExc_TypeError, | 
 | 123 | 				"function name must be a string"); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 124 | 		return NULL; | 
 | 125 | 	} | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 126 | 	func = dlsym(xp->dl_handle, PyString_AsString(name)); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 127 | 	if (func == NULL) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 128 | 		PyErr_SetString(PyExc_ValueError, dlerror()); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 129 | 		return NULL; | 
 | 130 | 	} | 
 | 131 | 	if (n-1 > 10) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 132 | 		PyErr_SetString(PyExc_TypeError, | 
 | 133 | 				"too many arguments (max 10)"); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 134 | 		return NULL; | 
 | 135 | 	} | 
 | 136 | 	for (i = 1; i < n; i++) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 137 | 		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 Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 143 | 			alist[i-1] = (long) ((char *)NULL); | 
 | 144 | 		else { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 145 | 			PyErr_SetString(PyExc_TypeError, | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 146 | 				   "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. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 154 | 	return PyInt_FromLong(res); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 155 | } | 
 | 156 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 157 | static 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 Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 162 | }; | 
 | 163 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 164 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 165 | dl_getattr(xp, name) | 
 | 166 | 	dlobject *xp; | 
 | 167 | 	char *name; | 
 | 168 | { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 169 | 	return Py_FindMethod(dlobject_methods, (PyObject *)xp, name); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 170 | } | 
 | 171 |  | 
 | 172 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 173 | static PyTypeObject Dltype = { | 
 | 174 | 	PyObject_HEAD_INIT(&PyType_Type) | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 175 | 	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. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 192 | static PyObject * | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 193 | dl_open(self, args) | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 194 | 	PyObject *self; | 
 | 195 | 	PyObject *args; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 196 | { | 
 | 197 | 	char *name; | 
 | 198 | 	int mode; | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 199 | 	PyUnivPtr *handle; | 
 | 200 | 	if (PyArg_Parse(args, "z", &name)) | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 201 | 		mode = RTLD_LAZY; | 
 | 202 | 	else { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 203 | 		PyErr_Clear(); | 
 | 204 | 		if (!PyArg_Parse(args, "(zi)", &name, &mode)) | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 205 | 			return NULL; | 
 | 206 | #ifndef RTLD_NOW | 
 | 207 | 		if (mode != RTLD_LAZY) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 208 | 			PyErr_SetString(PyExc_ValueError, "mode must be 1"); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 209 | 			return NULL; | 
 | 210 | 		} | 
 | 211 | #endif | 
 | 212 | 	} | 
 | 213 | 	handle = dlopen(name, mode); | 
 | 214 | 	if (handle == NULL) { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 215 | 		PyErr_SetString(Dlerror, dlerror()); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 216 | 		return NULL; | 
 | 217 | 	} | 
 | 218 | 	return newdlobject(handle); | 
 | 219 | } | 
 | 220 |  | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 221 | static PyMethodDef dl_methods[] = { | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 222 | 	{"open",	dl_open}, | 
 | 223 | 	{NULL,		NULL}		/* sentinel */ | 
 | 224 | }; | 
 | 225 |  | 
 | 226 | void | 
 | 227 | initdl() | 
 | 228 | { | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 229 | 	PyObject *m, *d, *x; | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 230 |  | 
 | 231 | 	if (sizeof(int) != sizeof(long) || | 
 | 232 | 	    sizeof(long) != sizeof(char *)) | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 233 | 		Py_FatalError( | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 234 |  "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)"); | 
 | 235 |  | 
 | 236 | 	/* Create the module and add the functions */ | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 237 | 	m = Py_InitModule("dl", dl_methods); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 238 |  | 
 | 239 | 	/* Add some symbolic constants to the module */ | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 240 | 	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 Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 245 | #ifdef RTLD_NOW | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 246 | 	x = PyInt_FromLong((long)RTLD_NOW); | 
 | 247 | 	PyDict_SetItemString(d, "RTLD_NOW", x); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 248 | #endif | 
 | 249 |  | 
 | 250 | 	/* Check for errors */ | 
| Roger E. Masse | 0e12032 | 1996-12-13 20:33:44 +0000 | [diff] [blame] | 251 | 	if (PyErr_Occurred()) | 
 | 252 | 		Py_FatalError("can't initialize module dl"); | 
| Guido van Rossum | 34162a1 | 1994-05-23 12:37:57 +0000 | [diff] [blame] | 253 | } |