Make pipe wait for its children
[minish.git] / src / ipc.h
blobfe50f199343747a96f9f52ff97059c7d54d19b0c
1 #ifndef IPC_H
2 #define IPC_H
4 #define _POSIX_C_SOURCE 200809L
5 #include <signal.h>
6 #include <stdbool.h>
7 #include <sys/wait.h>
8 #include <unistd.h>
9 #include "try.h"
11 typedef struct {
12 int read;
13 int write;
14 } Pipe;
16 static void accept_signal(int const signum, bool const accept) {
17 if (signal(signum, accept ? SIG_DFL : SIG_IGN) == SIG_ERR) {
18 pexit("signal()");
22 static void accept_interactive_signals(bool const accept) {
23 accept_signal(SIGINT, accept);
24 accept_signal(SIGQUIT, accept);
25 accept_signal(SIGTSTP, accept);
28 static Pipe make_pipe() {
29 Pipe p;
30 int fds[2];
31 if (pipe(fds) == -1) {
32 pexit("pipe()");
34 p.read = fds[0];
35 p.write = fds[1];
36 return p;
39 static void move_fd(int const old, int const new) {
40 if (dup2(old, new) == -1) {
41 pexit("dup2()");
43 close(old);
46 static int wait_script(pid_t const pid) {
47 int status = try_waitpid(pid, WUNTRACED);
48 while (WIFSTOPPED(status)) {
49 if (WSTOPSIG(status) == SIGTSTP) {
50 accept_signal(SIGTSTP, true);
51 raise(SIGTSTP);
52 accept_signal(SIGTSTP, false);
54 status = try_waitpid(pid, WUNTRACED);
56 if (WIFSIGNALED(status)) {
57 switch (WTERMSIG(status)) {
58 case SIGINT:
59 accept_signal(SIGINT, true);
60 raise(SIGINT);
61 case SIGQUIT: exit(EXIT_FAILURE);
64 return status;
67 #endif