From 3a75de9f8c7c61db183916f6d961046c2e6b4e1f Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Tue, 28 Jul 2020 13:01:15 -0600 Subject: [PATCH] execute: add lif_execute_buf_with_result() to collect a result buffer --- libifupdown/execute.c | 51 +++++++++++++++++++++++++++++++++++++++++++ libifupdown/execute.h | 1 + 2 files changed, 52 insertions(+) diff --git a/libifupdown/execute.c b/libifupdown/execute.c index b3781dc..09e2d98 100644 --- a/libifupdown/execute.c +++ b/libifupdown/execute.c @@ -60,6 +60,57 @@ lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const c return WIFEXITED(status) && WEXITSTATUS(status) == 0; } +bool +lif_execute_buf_with_result(const struct lif_execute_opts *opts, char *buf, size_t bufsize, char *const envp[], const char *fmt, ...) +{ + char cmdbuf[4096]; + va_list va; + + va_start(va, fmt); + vsnprintf(cmdbuf, sizeof cmdbuf, fmt, va); + va_end(va); + + pid_t child; + char *argv[] = { SHELL, "-c", cmdbuf, NULL }; + + if (opts->verbose) + puts(cmdbuf); + + if (opts->mock) + return true; + + int pipefds[2]; + if (pipe(pipefds) < 0) + { + fprintf(stderr, "execute '%s': %s\n", cmdbuf, strerror(errno)); + return false; + } + + posix_spawn_file_actions_t file_actions; + + posix_spawn_file_actions_init(&file_actions); + posix_spawn_file_actions_addclose(&file_actions, pipefds[0]); + posix_spawn_file_actions_adddup2(&file_actions, pipefds[1], 1); + posix_spawn_file_actions_addclose(&file_actions, pipefds[1]); + + if (posix_spawn(&child, SHELL, &file_actions, NULL, argv, envp) != 0) + { + fprintf(stderr, "execute '%s': %s\n", cmdbuf, strerror(errno)); + return false; + } + + int status; + waitpid(child, &status, 0); + + if (read(pipefds[0], buf, bufsize) < 0) + { + fprintf(stderr, "reading from pipe: %s\n", strerror(errno)); + return false; + } + + return WIFEXITED(status) && WEXITSTATUS(status) == 0; +} + bool lif_file_is_executable(const char *path) { diff --git a/libifupdown/execute.h b/libifupdown/execute.h index 491a35f..44391c9 100644 --- a/libifupdown/execute.h +++ b/libifupdown/execute.h @@ -27,6 +27,7 @@ struct lif_execute_opts { }; extern bool lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const char *fmt, ...); +extern bool lif_execute_buf_with_result(const struct lif_execute_opts *opts, char *buf, size_t bufsize, char *const envp[], const char *fmt, ...); extern bool lif_file_is_executable(const char *path); extern bool lif_maybe_run_executor(const struct lif_execute_opts *opts, char *const envp[], const char *executor);