diff options
Diffstat (limited to 'src/bin/utils.h')
-rw-r--r-- | src/bin/utils.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/bin/utils.h b/src/bin/utils.h new file mode 100644 index 0000000..3baa1b1 --- /dev/null +++ b/src/bin/utils.h @@ -0,0 +1,81 @@ +#pragma once + +// #include <spawn.h> +#include <sys/wait.h> +#include <unistd.h> + +struct proc { + pid_t pid; + int fds[2]; +}; + +static inline void +close_fd(int *fd) +{ + assert(fd); + if (*fd >= 0) + close(*fd); +} + +static inline bool +proc_open(const char *file, char *const argv[], struct proc *out_proc) +{ + assert(file && argv && out_proc); + *out_proc = (struct proc){0}; + + int pipes[4]; + pipe(&pipes[0]); /* parent */ + pipe(&pipes[2]); /* child */ + +#if 0 + // Doesn't work, no idea why + posix_spawn_file_actions_t fa; + if (posix_spawn_file_actions_init(&fa) != 0 || + posix_spawn_file_actions_addclose(&fa, pipes[0]) != 0 || + posix_spawn_file_actions_addclose(&fa, pipes[3]) != 0 || + posix_spawn_file_actions_adddup2(&fa, pipes[2], 0) != 0 || + posix_spawn_file_actions_adddup2(&fa, pipes[1], 1) != 0 || + posix_spawn_file_actions_addclose(&fa, pipes[2]) != 0 || + posix_spawn_file_actions_addclose(&fa, pipes[1]) != 0 || + posix_spawnp(&out_proc->pid, file, &fa, NULL, argv, NULL) != 0) { + posix_spawn_file_actions_destroy(&fa); + for (uint8_t i = 0; i < ARRAY_SIZE(pipes); ++i) + close(pipes[i]); + return false; + } + posix_spawn_file_actions_destroy(&fa); +#else + if ((out_proc->pid = fork()) > 0) { + out_proc->fds[0] = pipes[3]; + out_proc->fds[1] = pipes[0]; + close(pipes[1]); + close(pipes[2]); + return true; + } else { + close(pipes[0]); + close(pipes[3]); + dup2(pipes[2], 0); + dup2(pipes[1], 1); + close(pipes[2]); + close(pipes[1]); + execvp(file, argv); + _exit(0); + } +#endif + + out_proc->fds[0] = pipes[3]; + out_proc->fds[1] = pipes[0]; + close(pipes[1]); + close(pipes[2]); + return true; +} + +static inline void +proc_close(struct proc *proc) +{ + assert(proc); + waitpid(proc->pid, NULL, 0); + close_fd(&proc->fds[0]); + close_fd(&proc->fds[1]); + *proc = (struct proc){0}; +} |