]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
python: Add switch to return output on execute
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 4 Aug 2022 10:07:02 +0000 (10:07 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 4 Aug 2022 10:07:02 +0000 (10:07 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/jail.h
src/libpakfire/jail.c
src/libpakfire/libpakfire.sym

index 1d14df47d6fcaae00a38cc3ff4eda4b89e47ef9c..5e313fb04d096d9d3e41604bc7c055d3452f6166 100644 (file)
@@ -823,6 +823,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
                "interactive",
                "logging_callback",
                "nice",
+               "return_output",
                NULL
        };
 
@@ -831,6 +832,8 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
        int flags = 0;
        int r;
        PyObject* ret = NULL;
+       char** buffer = NULL;
+       char* output = NULL;
 
        PyObject* command = NULL;
        PyObject* environ = NULL;
@@ -838,9 +841,10 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
        int interactive = 0;
        PyObject* logging_callback = NULL;
        int nice = 0;
+       int return_output = 0;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OppOi", kwlist, &command, &environ,
-                       &enable_network, &interactive, &logging_callback, &nice))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OppOip", kwlist, &command, &environ,
+                       &enable_network, &interactive, &logging_callback, &nice, &return_output))
                return NULL;
 
        // Check if command is a list
@@ -940,7 +944,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
        }
 
        // Execute command
-       r = pakfire_jail_exec(jail, argv, NULL);
+       r = pakfire_jail_exec(jail, argv, (return_output) ? &buffer : NULL);
 
        // If the return code was negative, we had some internal error
        if (r < 0) {
@@ -958,13 +962,41 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
                goto ERROR;
        }
 
-       // Return None if everything was successful
-       ret = Py_None;
-       Py_INCREF(ret);
+       // The process has exited successfully
+
+       // Did the user request the output?
+       if (return_output) {
+               size_t length = 0;
+
+               // Join everything together into a long string
+               if (buffer) {
+                       output = pakfire_jail_concat_output(jail, (const char**)buffer, &length);
+                       if (!output) {
+                               PyErr_SetFromErrno(PyExc_OSError);
+                               goto ERROR;
+                       }
+               }
+
+               // Return the buffer as bytes
+               ret = PyBytes_FromStringAndSize(output, length);
+
+       // Otherwise just return None
+       } else {
+               ret = Py_None;
+               Py_INCREF(ret);
+       }
 
 ERROR:
        if (argv)
                free(argv);
+       if (buffer) {
+               for (char** line = buffer; *line; line++) {
+                       free(*line);
+               }
+               free(buffer);
+       }
+       if (output)
+               free(output);
 
        if (jail) {
                // Dereference the logging callback
index 9468af0a918b97e122ce7f2b9c76f1de13263d57..3025c5374444f45600a97c5de83002b541b5a1c0 100644 (file)
@@ -55,6 +55,10 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], char*** out
 int pakfire_jail_exec_script(struct pakfire_jail* jail,
        const char* script, const size_t size, const char* args[], char*** output);
 
+// Utility functions
+char* pakfire_jail_concat_output(struct pakfire_jail* jail,
+       const char** input, size_t* length);
+
 #ifdef PAKFIRE_PRIVATE
 
 // Convenience functions
index 221d08da1cc6b181055d92e5ccbef1b963c2aa11..4d63545911fca62db9b0d8830ff9c050f924e310 100644 (file)
@@ -1400,3 +1400,24 @@ int pakfire_jail_ldconfig(struct pakfire* pakfire) {
        // Run ldconfig
        return pakfire_jail_run(pakfire, argv, 0, NULL);
 }
+
+// Utility functions
+
+PAKFIRE_EXPORT char* pakfire_jail_concat_output(struct pakfire_jail* jail,
+               const char** input, size_t* length) {
+       // Return nothing on no input
+       if (!input)
+               return NULL;
+
+       // XXX Maybe there is a more efficient way to do this
+
+       char* output = pakfire_string_join((char**)input, "");
+       if (!output)
+               return NULL;
+
+       // Store the length of the result
+       if (length)
+               *length = strlen(output);
+
+       return output;
+}
index ab694b3c6f420587b78666ed31b8738240cec51e..bccd9cde868b690e18b534db57b57b56d7ced08b 100644 (file)
@@ -133,6 +133,7 @@ global:
        pakfire_key_unref;
 
        # jail
+       pakfire_jail_concat_output;
        pakfire_jail_create;
        pakfire_jail_exec;
        pakfire_jail_exec_script;