diff options
author | dec05eba <dec05eba@protonmail.com> | 2019-05-25 16:52:49 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2019-05-25 16:55:24 +0200 |
commit | 109c797d7c89223c9eed07dc322448b5c5fe3373 (patch) | |
tree | 20e538d4f5d558832d2984a1d60f810c387e9838 /src/Program.c | |
parent | 7cde49baf87b8340c608e76bc6052769deb1cdf4 (diff) |
Convert to sibs, add curl download, write test
Diffstat (limited to 'src/Program.c')
-rw-r--r-- | src/Program.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/Program.c b/src/Program.c new file mode 100644 index 0000000..526f64b --- /dev/null +++ b/src/Program.c @@ -0,0 +1,68 @@ +#include "../include/Program.h" +#include <unistd.h> +#include <sys/wait.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> + +#define READ_END 0 +#define WRITE_END 1 + +int exec_program(char **args, ProgramOutputCallback output_callback, void *userdata) { + /* 1 arguments */ + if(args[0] == NULL) + return -1; + + int fd[2]; + if(pipe(fd) == -1) { + perror("Failed to open pipe"); + return -2; + } + + pid_t pid = fork(); + if(pid == -1) { + perror("Failed to fork"); + return -3; + } else if(pid == 0) { /* child */ + dup2(fd[WRITE_END], STDOUT_FILENO); + close(fd[READ_END]); + close(fd[WRITE_END]); + + execv(args[0], args); + return 0; + } else { /* parent */ + close(fd[WRITE_END]); + + int status; + waitpid(pid, &status, 0); + if(!WIFEXITED(status)) + return -4; + + int exit_status = WEXITSTATUS(status); + if(exit_status != 0) { + fprintf(stderr, "Failed to execute program, exit status %d\n", exit_status); + return -exit_status; + } + + char buffer[2048]; + int result = 0; + + for(;;) { + ssize_t bytes_read = read(fd[READ_END], buffer, sizeof(buffer)); + if(bytes_read == 0) { + break; + } else if(bytes_read == -1) { + int err = errno; + fprintf(stderr, "Failed to read from pipe to program %s, error: %s\n", args[0], strerror(err)); + result = -err; + break; + } + + if(output_callback(buffer, bytes_read, userdata) != 0) + break; + } + + close(fd[READ_END]); + return result; + } +}
\ No newline at end of file |