* Execute
*/
+struct Pakfire_execute_output {
+ PyObject* stdout;
+ PyObject* stderr;
+};
+
static int Pakfire_execute_stdout_callback(struct pakfire_ctx* ctx, void* data,
const enum pakfire_jail_output_stream stream, const char* line, const size_t length) {
- PyObject** output = data;
+ struct Pakfire_execute_output* output = data;
PyObject* chunk = NULL;
- // Don't do anything for any error output
- if (stream == PAKFIRE_STDERR)
- return 0;
-
// Allocate a new chunk
chunk = PyBytes_FromStringAndSize(line, length);
if (!chunk)
return -ENOTSUP;
// Concatenate the chunk to the output
- PyBytes_ConcatAndDel(output, chunk);
+ switch (stream) {
+ case PAKFIRE_STDOUT:
+ PyBytes_ConcatAndDel(&output->stdout, chunk);
+ break;
+
+ case PAKFIRE_STDERR:
+ PyBytes_ConcatAndDel(&output->stderr, chunk);
+ break;
+ }
return 0;
}
PyObject* environ = NULL;
int nice = 0;
- PyObject* output = NULL;
+ struct Pakfire_execute_output output = {};
int return_output = 0;
const char* kwlist[] = {
}
}
- // Allocate a new output buffer
- output = PyBytes_FromString("");
- if (!output)
+ // Allocate a new output buffer for standard output
+ output.stdout = PyBytes_FromString("");
+ if (!output.stdout)
+ goto ERROR;
+
+ // Allocate a new output buffer for standard error
+ output.stderr = PyBytes_FromString("");
+ if (!output.stderr)
goto ERROR;
// Register the input callback
// Otherwise the executed command returned some error code
} else if (r > 0) {
- PyObject* error = Py_BuildValue("iO", r, output);
+ PyObject* error = Py_BuildValue("iO", r, output.stderr);
if (!error)
goto ERROR;
// Return the output if requested
if (return_output) {
- ret = Py_NewRef(output);
+ ret = Py_NewRef(output.stdout);
// Otherwise return None
} else {
if (argv)
free(argv);
- Py_XDECREF(output);
+ Py_XDECREF(output.stdout);
+ Py_XDECREF(output.stderr);
return ret;
}