]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: execute: Make logging functions exchangeable
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 16 Jan 2021 13:50:58 +0000 (13:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 16 Jan 2021 13:50:58 +0000 (13:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/execute.c
src/libpakfire/include/pakfire/execute.h
src/libpakfire/step.c
tests/libpakfire/execute.c

index aa471218d5d3085a00014fceb06cc00ae72ffcac..56d3c2a7ad62a382861b44b8226e43733c19e139 100644 (file)
@@ -454,7 +454,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
                flags |= PAKFIRE_EXECUTE_INTERACTIVE;
 
        // Execute command
-       int r = pakfire_execute(self->pakfire, argv, envp, flags);
+       int r = pakfire_execute(self->pakfire, argv, envp, flags, NULL);
 
        // Cleanup
        for (unsigned int i = 0; envp[i]; i++)
index 3d6ba3ffedc9e5e7052ac71ff06f35bc4ebc73c7..02fd2f0a7acd52dd092d041a690cef7a126581fd 100644 (file)
@@ -98,7 +98,8 @@ static int pakfire_execute_buffer_is_full(const struct pakfire_execute_buffer* b
        If it finds a whole line in it, it will send it to the logger and repeat the process.
        If not newline character is found, it will try to read more data until it finds one.
 */
-static int pakfire_execute_logger_proxy(Pakfire pakfire, int fd, struct pakfire_execute_buffer* buffer) {
+static int pakfire_execute_logger_proxy(Pakfire pakfire,
+               int(*log_func)(Pakfire pakfire, const char* data), int fd, struct pakfire_execute_buffer* buffer) {
        // Fill up buffer from fd
        while (buffer->used < buffer->size) {
                ssize_t bytes_read = read(fd, buffer->data + buffer->used,
@@ -133,7 +134,7 @@ static int pakfire_execute_logger_proxy(Pakfire pakfire, int fd, struct pakfire_
                                if (r)
                                        return -1;
 
-                               return pakfire_execute_logger_proxy(pakfire, fd, buffer);
+                               return pakfire_execute_logger_proxy(pakfire, log_func, fd, buffer);
                        }
 
                        // Otherwise we might have only read parts of the output
@@ -155,7 +156,9 @@ static int pakfire_execute_logger_proxy(Pakfire pakfire, int fd, struct pakfire_
                line[length] = '\0';
 
                // Log the line
-               INFO(pakfire, "%s", line);
+               int r = log_func(pakfire, line);
+               if (r)
+                       return r;
 
                // Remove line from buffer
                memmove(buffer->data, buffer->data + length, buffer->used - length);
@@ -165,7 +168,8 @@ static int pakfire_execute_logger_proxy(Pakfire pakfire, int fd, struct pakfire_
        return 0;
 }
 
-static int pakfire_execute_logger(Pakfire pakfire, pid_t pid, int stdout, int stderr, int* status) {
+static int pakfire_execute_logger(Pakfire pakfire, struct pakfire_execute_logger* logger,
+               pid_t pid, int stdout, int stderr, int* status) {
        int epollfd = -1;
        struct epoll_event ev;
        struct epoll_event events[EPOLL_MAX_EVENTS];
@@ -239,23 +243,26 @@ static int pakfire_execute_logger(Pakfire pakfire, pid_t pid, int stdout, int st
                }
 
                struct pakfire_execute_buffer* buffer;
+               int (*log_func)(Pakfire pakfire, const char* data);
 
                for (int i = 0; i < fds; i++) {
                        int fd = events[i].data.fd;
 
-                       if (fd == stdout)
+                       if (fd == stdout) {
                                buffer = &buffers.stdout;
+                               log_func = logger->log_stdout;
 
-                       else if (fd == stderr)
+                       } else if (fd == stderr) {
                                buffer = &buffers.stderr;
+                               log_func = logger->log_stderr;
 
-                       else {
+                       else {
                                DEBUG(pakfire, "Received invalid file descriptor %d\n", fd);
                                continue;
                        }
 
                        // Send everything to the logger
-                       r = pakfire_execute_logger_proxy(pakfire, fd, buffer);
+                       r = pakfire_execute_logger_proxy(pakfire, log_func, fd, buffer);
                        if (r)
                                goto OUT;
                }
@@ -272,6 +279,23 @@ OUT:
        return r;
 }
 
+static int default_log_stdout(Pakfire pakfire, const char* line) {
+       INFO(pakfire, "%s", line);
+
+       return 0;
+}
+
+static int default_log_stderr(Pakfire pakfire, const char* line) {
+       ERROR(pakfire, "%s", line);
+
+       return 0;
+}
+
+static struct pakfire_execute_logger default_logger = {
+       .log_stdout = default_log_stdout,
+       .log_stderr = default_log_stderr,
+};
+
 static int pakfire_execute_fork(void* data) {
        struct pakfire_execute* env = (struct pakfire_execute*)data;
 
@@ -344,7 +368,8 @@ static int pakfire_execute_fork(void* data) {
        return 1;
 }
 
-PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[], int flags) {
+PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[],
+               int flags, struct pakfire_execute_logger* logger) {
        struct pakfire_execute env = {
                .pakfire = pakfire,
                .argv = argv,
@@ -361,6 +386,9 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
        if (!env.envp)
                env.envp = envp_empty;
 
+       if (!logger)
+               logger = &default_logger;
+
        // Configure the new namespace
        int cflags = CLONE_VFORK | SIGCHLD | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUTS;
 
@@ -406,7 +434,7 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
                if (env.stderr[1])
                        close(env.stderr[1]);
 
-               if (pakfire_execute_logger(pakfire, pid, env.stdout[0], env.stderr[0], &status)) {
+               if (pakfire_execute_logger(pakfire, logger, pid, env.stdout[0], env.stderr[0], &status)) {
                        ERROR(pakfire, "Log reading aborted: %s\n", strerror(errno));
                }
        }
@@ -431,10 +459,11 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
        return r;
 }
 
-PAKFIRE_EXPORT int pakfire_execute_command(Pakfire pakfire, const char* command, char* envp[], int flags) {
+PAKFIRE_EXPORT int pakfire_execute_command(Pakfire pakfire, const char* command, char* envp[],
+               int flags, struct pakfire_execute_logger* logger) {
        const char* argv[2] = {
                command, NULL,
        };
 
-       return pakfire_execute(pakfire, argv, envp, flags);
+       return pakfire_execute(pakfire, argv, envp, flags, logger);
 }
index 30713f02952d18f98f9b7b70f06f7cc926292538..cff8b576aae8e3fc6e4e2ab7ff22284507f491ba 100644 (file)
 
 #include <pakfire/types.h>
 
-int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[], int flags);
-int pakfire_execute_command(Pakfire pakfire, const char* command, char* envp[], int flags);
+struct pakfire_execute_logger {
+       int (*log_stdout)(Pakfire pakfire, const char* data);
+       int (*log_stderr)(Pakfire pakfire, const char* data);
+};
+
+int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[],
+       int flags, struct pakfire_execute_logger* logger);
+int pakfire_execute_command(Pakfire pakfire, const char* command, char* envp[],
+       int flags, struct pakfire_execute_logger* logger);
 
 enum {
        PAKFIRE_EXECUTE_NONE                    = 0,
index 321fb614c75790fe337ed33176c6099ac9c54edb..59f857cadc4f8a5c316a77ea589599352cf20329 100644 (file)
@@ -365,7 +365,7 @@ static int pakfire_step_run_shell_script(PakfireStep step, const char* data, con
                command = pakfire_path_relpath(root, path);
 
        // Run the script
-       r = pakfire_execute_command(step->pakfire, command, NULL, 0);
+       r = pakfire_execute_command(step->pakfire, command, NULL, 0, NULL);
        if (r) {
                DEBUG(step->pakfire, "Script return code: %d\n", r);
        }
@@ -422,7 +422,7 @@ static int pakfire_run_ldconfig(PakfireStep step) {
        const char* path = pakfire_get_path(step->pakfire);
 
        if (pakfire_access(step->pakfire, path, LDCONFIG, X_OK) == 0) {
-               r = pakfire_execute_command(step->pakfire, LDCONFIG, NULL, 0);
+               r = pakfire_execute_command(step->pakfire, LDCONFIG, NULL, 0, NULL);
 
                DEBUG(step->pakfire, "ldconfig returned %d\n", r);
        }
index 856a24b7001d3de5bb095f8a0a51a43943b6f48d..330add11adc4d8ae48e95862545476f79599931e 100644 (file)
@@ -30,7 +30,7 @@ static const char* cmd[2] = {
 };
 
 static int test_does_not_exist(const struct test* t) {
-       int r = pakfire_execute(t->pakfire, cmd, NULL, 0);
+       int r = pakfire_execute(t->pakfire, cmd, NULL, 0, NULL);
        ASSERT(r != 0);
 
        return EXIT_SUCCESS;