Я реализую простую оболочку, в которой дочернему процессу с собственным PGID предоставляется управление терминалом.
Проблема в том, что когда я останавливаю дочерний процесс с помощью SIGTSTP (ctrl + z), терминалапросто зависает и застревает в waitpid:
Как получить waitpid, чтобы перестать зависать?
void wait_job() {
int status;
int corpse;
int wait_flags = WUNTRACED | WCONTINUED;
while ((corpse = waitpid(-1, &status, wait_flags)) > 0) {
if (WIFSTOPPED(status)) {
printf("child stopped, sign num = %d, corpse = %d\n", WSTOPSIG(status), corpse);
}
else if (WIFEXITED(status)) {
printf("child exited, sign num = %d, corpse = %d\n", status, corpse);
}
else if (WIFCONTINUED(status)) {
printf("child continued, sign num = %d, corpse = %d\n", status, corpse);
}
}
}
int main() {
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
char buffer[100];
char prompt[] = "Press enter: ";
while (1) {
write(STDOUT_FILENO, prompt, sizeof(prompt) - 1);
int n = read(STDIN_FILENO, buffer, 10);
buffer[n - 1] = '\0';
int pid;
if ((pid = fork()) == 0) { // Child
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
signal(SIGTTIN, SIG_DFL);
signal(SIGTTOU, SIG_DFL);
setpgid(pid, pid);
tcsetpgrp(STDIN_FILENO, pid);
char* argv[] = { "sleep", "5", NULL };
execvp(argv[0], argv);
exit(0);
}
// Parent
setpgid(pid, pid);
tcsetpgrp(STDIN_FILENO, pid);
wait_job();
tcsetpgrp(STDIN_FILENO, getpgid(0));
}
}