libidav/utils.c

changeset 731
e0358fa1a3b1
parent 723
5ca174b3247a
child 737
1c75c0498520
--- 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 <unistd.h>
+#include <spawn.h>
+#include <sys/wait.h>
 #include <termios.h>
 #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;

mercurial