home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / dlmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  5.0 KB  |  247 lines

  1.  
  2. /* dl module */
  3.  
  4. #include "Python.h"
  5.  
  6. #include <dlfcn.h>
  7.  
  8. #ifndef RTLD_LAZY
  9. #define RTLD_LAZY 1
  10. #endif
  11.  
  12. typedef void *PyUnivPtr;
  13. typedef struct {
  14.     PyObject_HEAD
  15.     PyUnivPtr *dl_handle;
  16. } dlobject;
  17.  
  18. staticforward PyTypeObject Dltype;
  19.  
  20. static PyObject *Dlerror;
  21.  
  22. static PyObject *
  23. newdlobject(PyUnivPtr *handle)
  24. {
  25.     dlobject *xp;
  26.     xp = PyObject_New(dlobject, &Dltype);
  27.     if (xp == NULL)
  28.         return NULL;
  29.     xp->dl_handle = handle;
  30.     return (PyObject *)xp;
  31. }
  32.  
  33. static void
  34. dl_dealloc(dlobject *xp)
  35. {
  36.     if (xp->dl_handle != NULL)
  37.         dlclose(xp->dl_handle);
  38.     PyObject_Del(xp);
  39. }
  40.  
  41. static PyObject *
  42. dl_close(dlobject *xp, PyObject *args)
  43. {
  44.     if (!PyArg_Parse(args, ""))
  45.         return NULL;
  46.     if (xp->dl_handle != NULL) {
  47.         dlclose(xp->dl_handle);
  48.         xp->dl_handle = NULL;
  49.     }
  50.     Py_INCREF(Py_None);
  51.     return Py_None;
  52. }
  53.  
  54. static PyObject *
  55. dl_sym(dlobject *xp, PyObject *args)
  56. {
  57.     char *name;
  58.     PyUnivPtr *func;
  59.     if (!PyArg_Parse(args, "s", &name))
  60.         return NULL;
  61.     func = dlsym(xp->dl_handle, name);
  62.     if (func == NULL) {
  63.         Py_INCREF(Py_None);
  64.         return Py_None;
  65.     }
  66.     return PyInt_FromLong((long)func);
  67. }
  68.  
  69. static PyObject *
  70. dl_call(dlobject *xp, PyObject *args)
  71. {
  72.     PyObject *name;
  73.     long (*func)(long, long, long, long, long,
  74.                      long, long, long, long, long);
  75.     long alist[10];
  76.     long res;
  77.     int i;
  78.     int n = PyTuple_Size(args);
  79.     if (n < 1) {
  80.         PyErr_SetString(PyExc_TypeError, "at least a name is needed");
  81.         return NULL;
  82.     }
  83.     name = PyTuple_GetItem(args, 0);
  84.     if (!PyString_Check(name)) {
  85.         PyErr_SetString(PyExc_TypeError,
  86.                 "function name must be a string");
  87.         return NULL;
  88.     }
  89.     func = dlsym(xp->dl_handle, PyString_AsString(name));
  90.     if (func == NULL) {
  91.         PyErr_SetString(PyExc_ValueError, dlerror());
  92.         return NULL;
  93.     }
  94.     if (n-1 > 10) {
  95.         PyErr_SetString(PyExc_TypeError,
  96.                 "too many arguments (max 10)");
  97.         return NULL;
  98.     }
  99.     for (i = 1; i < n; i++) {
  100.         PyObject *v = PyTuple_GetItem(args, i);
  101.         if (PyInt_Check(v))
  102.             alist[i-1] = PyInt_AsLong(v);
  103.         else if (PyString_Check(v))
  104.             alist[i-1] = (long)PyString_AsString(v);
  105.         else if (v == Py_None)
  106.             alist[i-1] = (long) ((char *)NULL);
  107.         else {
  108.             PyErr_SetString(PyExc_TypeError,
  109.                    "arguments must be int, string or None");
  110.             return NULL;
  111.         }
  112.     }
  113.     for (; i <= 10; i++)
  114.         alist[i-1] = 0;
  115.     res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4],
  116.               alist[5], alist[6], alist[7], alist[8], alist[9]);
  117.     return PyInt_FromLong(res);
  118. }
  119.  
  120. static PyMethodDef dlobject_methods[] = {
  121.     {"call",    (PyCFunction)dl_call,    1 /* varargs */},
  122.     {"sym",     (PyCFunction)dl_sym},
  123.     {"close",    (PyCFunction)dl_close},
  124.     {NULL,      NULL}             /* Sentinel */
  125. };
  126.  
  127. static PyObject *
  128. dl_getattr(dlobject *xp, char *name)
  129. {
  130.     return Py_FindMethod(dlobject_methods, (PyObject *)xp, name);
  131. }
  132.  
  133.  
  134. static PyTypeObject Dltype = {
  135.     PyObject_HEAD_INIT(&PyType_Type)
  136.     0,            /*ob_size*/
  137.     "dl",            /*tp_name*/
  138.     sizeof(dlobject),    /*tp_basicsize*/
  139.     0,            /*tp_itemsize*/
  140.     /* methods */
  141.     (destructor)dl_dealloc, /*tp_dealloc*/
  142.     0,            /*tp_print*/
  143.     (getattrfunc)dl_getattr,/*tp_getattr*/
  144.     0,            /*tp_setattr*/
  145.     0,            /*tp_compare*/
  146.     0,            /*tp_repr*/
  147.     0,            /*tp_as_number*/
  148.     0,            /*tp_as_sequence*/
  149.     0,            /*tp_as_mapping*/
  150.     0,            /*tp_hash*/
  151. };
  152.  
  153. static PyObject *
  154. dl_open(PyObject *self, PyObject *args)
  155. {
  156.     char *name;
  157.     int mode;
  158.     PyUnivPtr *handle;
  159.     if (PyArg_Parse(args, "z", &name))
  160.         mode = RTLD_LAZY;
  161.     else {
  162.         PyErr_Clear();
  163.         if (!PyArg_Parse(args, "(zi)", &name, &mode))
  164.             return NULL;
  165. #ifndef RTLD_NOW
  166.         if (mode != RTLD_LAZY) {
  167.             PyErr_SetString(PyExc_ValueError, "mode must be 1");
  168.             return NULL;
  169.         }
  170. #endif
  171.     }
  172.     handle = dlopen(name, mode);
  173.     if (handle == NULL) {
  174.         PyErr_SetString(Dlerror, dlerror());
  175.         return NULL;
  176.     }
  177.     return newdlobject(handle);
  178. }
  179.  
  180. static PyMethodDef dl_methods[] = {
  181.     {"open",    dl_open},
  182.     {NULL,        NULL}        /* sentinel */
  183. };
  184.  
  185. /* From socketmodule.c
  186.  * Convenience routine to export an integer value.
  187.  *
  188.  * Errors are silently ignored, for better or for worse...
  189.  */
  190. static void
  191. insint(PyObject *d, char *name, int value)
  192. {
  193.     PyObject *v = PyInt_FromLong((long) value);
  194.     if (!v || PyDict_SetItemString(d, name, v))
  195.         PyErr_Clear();
  196.  
  197.     Py_XDECREF(v);
  198. }
  199.  
  200. void
  201. initdl(void)
  202. {
  203.     PyObject *m, *d, *x;
  204.  
  205.     if (sizeof(int) != sizeof(long) ||
  206.         sizeof(long) != sizeof(char *)) {
  207.         PyErr_SetString(PyExc_SystemError,
  208.  "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)");
  209.         return;
  210.     }
  211.  
  212.     /* Create the module and add the functions */
  213.     m = Py_InitModule("dl", dl_methods);
  214.  
  215.     /* Add some symbolic constants to the module */
  216.     d = PyModule_GetDict(m);
  217.     Dlerror = x = PyErr_NewException("dl.error", NULL, NULL);
  218.     PyDict_SetItemString(d, "error", x);
  219.     x = PyInt_FromLong((long)RTLD_LAZY);
  220.     PyDict_SetItemString(d, "RTLD_LAZY", x);
  221. #define INSINT(X)    insint(d,#X,X)
  222. #ifdef RTLD_NOW
  223.         INSINT(RTLD_NOW);
  224. #endif
  225. #ifdef RTLD_NOLOAD
  226.         INSINT(RTLD_NOLOAD);
  227. #endif
  228. #ifdef RTLD_GLOBAL
  229.         INSINT(RTLD_GLOBAL);
  230. #endif
  231. #ifdef RTLD_LOCAL
  232.         INSINT(RTLD_LOCAL);
  233. #endif
  234. #ifdef RTLD_PARENT
  235.         INSINT(RTLD_PARENT);
  236. #endif
  237. #ifdef RTLD_GROUP
  238.         INSINT(RTLD_GROUP);
  239. #endif
  240. #ifdef RTLD_WORLD
  241.         INSINT(RTLD_WORLD);
  242. #endif
  243. #ifdef RTLD_NODELETE
  244.         INSINT(RTLD_NODELETE);
  245. #endif
  246. }
  247.