waitpid () зависает, когда дочерний процесс переднего плана останавливается SIGTSTP - PullRequest
0 голосов
/ 12 февраля 2019

Я реализую простую оболочку, в которой дочернему процессу с собственным PGID предоставляется управление терминалом.

Проблема в том, что когда я останавливаю дочерний процесс с помощью SIGTSTP (ctrl + z), терминалапросто зависает и застревает в waitpid:

enter image description here

Как получить 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));
    }
}
...