From: Michael Tremer Date: Sat, 16 Jan 2021 13:50:58 +0000 (+0000) Subject: libpakfire: execute: Make logging functions exchangeable X-Git-Tag: 0.9.28~1285^2~849 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb5d4fd15e2f14a80c22a5f02b428d12131739ef;p=pakfire.git libpakfire: execute: Make logging functions exchangeable Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index aa471218d..56d3c2a7a 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -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++) diff --git a/src/libpakfire/execute.c b/src/libpakfire/execute.c index 3d6ba3ffe..02fd2f0a7 100644 --- a/src/libpakfire/execute.c +++ b/src/libpakfire/execute.c @@ -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); } diff --git a/src/libpakfire/include/pakfire/execute.h b/src/libpakfire/include/pakfire/execute.h index 30713f029..cff8b576a 100644 --- a/src/libpakfire/include/pakfire/execute.h +++ b/src/libpakfire/include/pakfire/execute.h @@ -23,8 +23,15 @@ #include -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, diff --git a/src/libpakfire/step.c b/src/libpakfire/step.c index 321fb614c..59f857cad 100644 --- a/src/libpakfire/step.c +++ b/src/libpakfire/step.c @@ -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); } diff --git a/tests/libpakfire/execute.c b/tests/libpakfire/execute.c index 856a24b70..330add11a 100644 --- a/tests/libpakfire/execute.c +++ b/tests/libpakfire/execute.c @@ -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;