From 2198478cd22cec4ea2b645d4e9f31ee9c2508ff5 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Tue, 9 Oct 2018 08:49:46 +0300 Subject: push for remote work --- src/bin/utils.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/bin/utils.h (limited to 'src/bin/utils.h') 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 +#include +#include + +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}; +} -- cgit v1.2.3