[Open-scap] [PATCH] added a python-only function to allow python callable to be registered as a callback

Marshall Miller mmiller at tresys.com
Thu Jun 10 17:28:02 UTC 2010


This is a way to get around swig limitations related to callbacks.
To register a callback from python, call xccdf_policy_model_register_callback_py
with a python callable as the callback.
---
 swig/openscap.i |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/swig/openscap.i b/swig/openscap.i
index 5d414fd..c367a25 100644
--- a/swig/openscap.i
+++ b/swig/openscap.i
@@ -34,9 +34,6 @@
 #if defined(SWIGPYTHON)
 /* Definitions for PYTHON */
 
-%ignore xccdf_policy_evaluate;
-%ignore xccdf_policy_model_register_callback;
-
 %typemap(in) time_t
 {
     if (PyLong_Check($input))
@@ -241,3 +238,60 @@
 }
 
 */
+
+#if defined(SWIGPYTHON)
+%{
+struct internal_usr {
+    PyObject *func;
+    PyObject *usr;
+};
+
+static bool xccdf_policy_model_callback_wrapper(struct xccdf_policy_model *model, char *href, char *id, void *usr)
+{
+    PyGILState_STATE state;
+    PyObject *arglist;
+    PyObject *pymodel;
+    PyObject *func, *usrdata;
+    struct internal_usr *data;
+    PyObject *result;
+    double    dres = 0;
+
+    pymodel = SWIG_NewPointerObj(model, SWIGTYPE_p_xccdf_policy_model, 1);
+    data = (struct internal_usr *)usr;
+    func = data->func;
+    state = PyGILState_Ensure();
+    usrdata = data->usr;
+    arglist = Py_BuildValue("OssO", pymodel, href, id, usrdata);
+    if (!PyCallable_Check(func)) {
+      PyGILState_Release(state);
+      return false;
+    }
+    result = PyEval_CallObject(func,arglist);
+    Py_DECREF(arglist);
+    if (PyObject_IsTrue(result)) {
+        dres = true;
+    } else {
+        dres = false;
+    }
+    Py_XDECREF(result);
+    PyGILState_Release(state);
+    return dres;
+}
+%}
+
+%inline %{
+bool xccdf_policy_model_register_callback_py(struct xccdf_policy_model *model, char *sys, PyObject *func, PyObject *usr) {
+    struct internal_usr *new_usrdata;
+    PyEval_InitThreads();
+    Py_INCREF(func);
+    Py_INCREF(usr);
+    new_usrdata = oscap_alloc(sizeof(struct internal_usr));
+    if (new_usrdata == NULL) return false;
+
+    new_usrdata->func = func;
+    new_usrdata->usr = usr;
+  
+    return xccdf_policy_model_register_callback(model,sys,xccdf_policy_model_callback_wrapper,(void *)new_usrdata);
+}
+%}
+#endif
-- 
1.6.2.5




More information about the Open-scap-list mailing list