static int Pakfire_execute_output_callback(struct pakfire_ctx* ctx, struct pakfire_jail* jail,
void* data, const char* line, size_t length) {
PyObject* callback = (PyObject*)data;
- int r = 0;
+ PyObject* args = NULL;
+ PyObject* result = NULL;
+ int r = 1;
// Do nothing if callback isn't set
if (!callback)
return 0;
// Remove the trailing newline
- if (line && line[length - 1] == '\n')
+ if (line && length && line[length - 1] == '\n')
length--;
+ // Get the GIL
+ PyGILState_STATE state = PyGILState_Ensure();
+
// Create tuple with arguments for the callback function
- PyObject* args = Py_BuildValue("(is#)", LOG_INFO, line, (Py_ssize_t)length);
+ args = Py_BuildValue("(is#)", LOG_INFO, line, (Py_ssize_t)length);
if (!args)
- return 1;
+ goto ERROR;
- PyObject* result = PyObject_CallObject(callback, args);
+ // Call the callback method
+ result = PyObject_CallObject(callback, args);
if (result && PyLong_Check(result)) {
r = PyLong_AsLong(result);
}
+ERROR:
Py_XDECREF(args);
Py_XDECREF(result);
+ // Release the GIL
+ PyGILState_Release(state);
+
return r;
}
if (!PyUnicode_Check(item)) {
PyErr_Format(PyExc_TypeError, "Item %u in command is not a string", i);
- return NULL;
+ goto ERROR;
}
// Copy to argv
goto ERROR;
}
- // Check callback
- if (callback && !PyCallable_Check(callback)) {
- PyErr_SetString(PyExc_TypeError, "callback must be callable\n");
- goto ERROR;
- }
-
// Set nice
if (nice) {
r = pakfire_jail_nice(jail, nice);
}
}
- const Py_ssize_t num_bind = PySequence_Length(bind);
-
// Bind
- for (unsigned int i = 0; i < num_bind; i++) {
- PyObject* b = PySequence_ITEM(bind, i);
- if (!b)
- goto ERROR;
+ if (bind && PySequence_Check(bind)) {
+ const Py_ssize_t num_bind = PySequence_Length(bind);
- // Check if this is a Unicode object
- if (!PyUnicode_Check(b)) {
- PyErr_SetString(PyExc_ValueError, "bind contains a non-Unicode object");
- Py_DECREF(b);
- goto ERROR;
- }
+ for (unsigned int i = 0; i < num_bind; i++) {
+ PyObject* b = PySequence_ITEM(bind, i);
+ if (!b)
+ goto ERROR;
+
+ // Check if this is a Unicode object
+ if (!PyUnicode_Check(b)) {
+ PyErr_SetString(PyExc_ValueError, "bind contains a non-Unicode object");
+ Py_DECREF(b);
+ goto ERROR;
+ }
- const char* path = PyUnicode_AsUTF8(b);
+ const char* path = PyUnicode_AsUTF8(b);
+
+ // Perform bind
+ r = pakfire_jail_bind(jail, path, path, 0);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ Py_DECREF(b);
+ goto ERROR;
+ }
- // Perform bind
- r = pakfire_jail_bind(jail, path, path, 0);
- if (r) {
- PyErr_SetFromErrno(PyExc_OSError);
Py_DECREF(b);
- goto ERROR;
}
-
- Py_DECREF(b);
}
Py_BEGIN_ALLOW_THREADS