aboutsummaryrefslogtreecommitdiff
path: root/program.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-07-13 15:59:30 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-13 15:59:30 +0200
commitae0520e57267dbd866fc8cd25f66f4e6af2ac118 (patch)
tree22788688f1b588c3ad00c1ce3fe13da68b3a9382 /program.c
parenta1ca82847eb356c6b85ada2ac11f38d98f6e085e (diff)
Move c files into src directory
Diffstat (limited to 'program.c')
-rw-r--r--program.c111
1 files changed, 0 insertions, 111 deletions
diff --git a/program.c b/program.c
deleted file mode 100644
index c396695..0000000
--- a/program.c
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "program.h"
-#include "buffer.h"
-#include <unistd.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define READ_END 0
-#define WRITE_END 1
-
-int program_buffer_write_callback(char *data, int size, void *userdata) {
- Buffer *buffer = userdata;
- buffer_append(buffer, data, size);
- return 0;
-}
-
-int program_exec(const 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 parent_pid = getpid();
-
- pid_t pid = fork();
- if(pid == -1) {
- perror("Failed to fork");
- return -3;
- } else if(pid == 0) { /* child */
- if(prctl(PR_SET_PDEATHSIG, SIGTERM) == -1) {
- perror("prctl(PR_SET_PDEATHSIG, SIGTERM) failed");
- exit(127);
- }
-
- /* Test if the parent died before the above call to prctl */
- if(getppid() != parent_pid)
- exit(127);
-
- dup2(fd[WRITE_END], STDOUT_FILENO);
- close(fd[READ_END]);
- close(fd[WRITE_END]);
-
- execvp(args[0], (char* const*)args);
- perror("execvp");
- exit(127);
- } else { /* parent */
- close(fd[WRITE_END]);
-
- int result = 0;
- int status;
-
- char buffer[4097];
-
- if(output_callback) {
- for(;;) {
- ssize_t bytes_read = read(fd[READ_END], buffer, sizeof(buffer) - 1);
- 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;
- goto cleanup;
- }
-
- buffer[bytes_read] = '\0';
- if(output_callback(buffer, bytes_read, userdata) != 0)
- break;
- }
- }
-
- if(waitpid(pid, &status, 0) == -1) {
- perror("waitpid failed");
- result = -5;
- goto cleanup;
- }
-
- if(!WIFEXITED(status)) {
- result = -4;
- goto cleanup;
- }
-
- int exit_status = WEXITSTATUS(status);
- if(exit_status != 0) {
- fprintf(stderr, "Failed to execute program (");
- const char **arg = args;
- while(*arg) {
- if(arg != args)
- fputc(' ', stderr);
- fprintf(stderr, "'%s'", *arg);
- ++arg;
- }
- fprintf(stderr, "), exit status %d\n", exit_status);
- result = -exit_status;
- goto cleanup;
- }
-
- cleanup:
- close(fd[READ_END]);
- return result;
- }
-}