当前台子进程停止SIGTSTP时,waitpid()挂起

时间:2019-02-12 03:05:28

标签: c unix signals wait child-process

我正在实现一个简单的外壳程序,在该外壳程序中,具有自己的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));
    }
}

0 个答案:

没有答案