]> git.ipfire.org Git - pakfire.git/commitdiff
python: execute: Capture stdout/stderr separately
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Mar 2025 10:30:14 +0000 (10:30 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Mar 2025 10:30:14 +0000 (10:30 +0000)
That way, we can raise the error output and return the rest

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/python/pakfire.c

index 5bb720aabb4137f7ec7869378ec758cbc0a33b52..884020b607abd9d00b9779093dc2027bf1054ab2 100644 (file)
@@ -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;
 }