diff -r 83f832e345e0 -r e0358fa1a3b1 libidav/utils.c --- a/libidav/utils.c Sun Aug 08 11:45:36 2021 +0200 +++ b/libidav/utils.c Sun Aug 08 12:45:31 2021 +0200 @@ -44,6 +44,9 @@ #define IS_PATH_SEPARATOR(c) (c == '/' || c == '\\') #define PATH_SEPARATOR '\\' #else +#include +#include +#include #include #define getpasswordchar() getchar() #define IS_PATH_SEPARATOR(c) (c == '/') @@ -1114,6 +1117,55 @@ return str; } +int util_exec_command(char *command, UcxBuffer *outbuf) { +#ifdef _WIN32 + fprintf(stderr, "util_exec_command unsupported\n"); + return NULL; +#endif + + int pout[2]; + if(pipe(pout)) { + perror("pipe"); + return 1; + } + + int ret = 0; + + // close stdin and stderr, use pipe for stdout + posix_spawn_file_actions_t actions; + posix_spawn_file_actions_init(&actions); + posix_spawn_file_actions_addclose(&actions, 0); + posix_spawn_file_actions_adddup2(&actions, pout[1], 1); + posix_spawn_file_actions_addclose(&actions, 2); + + char *args[4]; + args[0] = "sh"; + args[1] = "-c"; + args[2] = command; + args[3] = NULL; + + pid_t pid; // child pid + ret = posix_spawn(&pid, "/bin/sh", &actions, NULL, args, NULL); + + close(pout[1]); + + if(!ret) { + ssize_t r; + char buf[1024]; + while((r = read(pout[0], buf, 1024)) > 0) { + ucx_buffer_write(buf, 1, r, outbuf); + } + } + + // wait for child process + ret = 1; + waitpid(pid, &ret, 0); + + posix_spawn_file_actions_destroy(&actions); + close(pout[0]); + + return ret; +} char* util_hexstr(const unsigned char *data, size_t len) { size_t buflen = 2*len + 4;