execute: add lif_execute_buf_with_result() to collect a result buffer

This commit is contained in:
Ariadne Conill 2020-07-28 13:01:15 -06:00
parent 3302089d4b
commit 3a75de9f8c
2 changed files with 52 additions and 0 deletions

View file

@ -60,6 +60,57 @@ lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const c
return WIFEXITED(status) && WEXITSTATUS(status) == 0; 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 bool
lif_file_is_executable(const char *path) lif_file_is_executable(const char *path)
{ {

View file

@ -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_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_file_is_executable(const char *path);
extern bool lif_maybe_run_executor(const struct lif_execute_opts *opts, char *const envp[], const char *executor); extern bool lif_maybe_run_executor(const struct lif_execute_opts *opts, char *const envp[], const char *executor);