From: Michael Tremer Date: Wed, 26 Mar 2025 10:30:14 +0000 (+0000) Subject: python: execute: Capture stdout/stderr separately X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f673df4e596af765342c7dc1b47eaeceac91816e;p=pakfire.git python: execute: Capture stdout/stderr separately That way, we can raise the error output and return the rest Signed-off-by: Michael Tremer --- diff --git a/src/python/pakfire.c b/src/python/pakfire.c index 5bb720aa..884020b6 100644 --- a/src/python/pakfire.c +++ b/src/python/pakfire.c @@ -533,22 +533,31 @@ ERROR: * 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; } @@ -570,7 +579,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject* PyObject* environ = NULL; int nice = 0; - PyObject* output = NULL; + struct Pakfire_execute_output output = {}; int return_output = 0; const char* kwlist[] = { @@ -653,9 +662,14 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject* } } - // 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 @@ -696,7 +710,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject* // 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; @@ -709,7 +723,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject* // Return the output if requested if (return_output) { - ret = Py_NewRef(output); + ret = Py_NewRef(output.stdout); // Otherwise return None } else { @@ -724,7 +738,8 @@ ERROR: if (argv) free(argv); - Py_XDECREF(output); + Py_XDECREF(output.stdout); + Py_XDECREF(output.stderr); return ret; }