"interactive",
"logging_callback",
"nice",
+ "return_output",
NULL
};
int flags = 0;
int r;
PyObject* ret = NULL;
+ char** buffer = NULL;
+ char* output = NULL;
PyObject* command = NULL;
PyObject* environ = NULL;
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
}
// 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) {
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
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
// 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;
+}