1 #define _POSIX_C_SOURCE 200809L
3 #include <fcntl.h> // O_RDONLY,open
4 #include <locale.h> // LC_ALL,setlocale
5 #include <signal.h> /* SIGHUP,SIGINT,SIGQUIT,SIGTSTP,SIGTTOU,
6 * SIG_DFL,SIG_ERR,SIG_IGN,signal,raise
8 #include <stdio.h> // feof,ferror,fputs,perror,stderr,stdin
9 #include <stdlib.h> // EXIT_FAILURE,exit
10 #include <stdnoreturn.h> // noreturn
11 #include <sys/wait.h> /* WIFSIGNALED,WIFSTOPPED,WSTOPSIG,WTERMSIG,
14 #include <unistd.h> // close,dup2,execv,fork,pid_t,setpgid,tcsetpgrp
16 #define TRY(f, ...) do {\
17 if (f(__VA_ARGS__) == -1) {\
22 static noreturn
void pexit(char const* const filename
) {
23 fputs("minish: ", stderr
);
28 static void try_signal(int const signum
, void (* const handler
)(int)) {
29 if (signal(signum
, handler
) == SIG_ERR
) {
34 int main(int argc
, char** argv
) {
35 setlocale(LC_ALL
, "");
37 int const input
= open(argv
[1], O_RDONLY
);
42 try_signal(SIGINT
, SIG_IGN
);
43 try_signal(SIGQUIT
, SIG_IGN
);
44 try_signal(SIGTSTP
, SIG_IGN
);
48 pid_t
const pid
= fork();
50 case -1: pexit("fork()");
53 try_signal(SIGINT
, SIG_DFL
);
54 try_signal(SIGQUIT
, SIG_DFL
);
55 try_signal(SIGTSTP
, SIG_DFL
);
58 char const* const tty
= "/dev/tty";
59 int const fd
= open(tty
, O_RDONLY
);
63 try_signal(SIGTTOU
, SIG_IGN
);
64 TRY(tcsetpgrp
, fd
, getpid());
65 try_signal(SIGTTOU
, SIG_DFL
);
68 char const* const name
= "minish-once";
69 execl("./minish-once", name
, (char const*)0);
72 TRY(waitpid
, pid
, &s
, WUNTRACED
);
75 switch (WTERMSIG(s
)) {
77 try_signal(SIGINT
, SIG_DFL
);
79 case SIGQUIT
: return EXIT_FAILURE
;
82 if (WIFSTOPPED(s
) && WSTOPSIG(s
) == SIGTSTP
) {
83 try_signal(SIGTSTP
, SIG_DFL
);
87 } while (!WIFSIGNALED(s
) || WTERMSIG(s
) != SIGHUP
);