C++ SIGTSTP后如何返回壳牌

C++ SIGTSTP后如何返回壳牌,c++,shell,signals,posix,sigint,C++,Shell,Signals,Posix,Sigint,我正在unixshell上写东西 按下CTRL-C时,发送SIGINT信号。他在工作! 但当按下CTRL-Z时,获取信号的过程停止,但我无法返回shell。只有关闭流程,我才能返回 这是我的信号处理器: 您需要检查您孩子的状态,以查看他们何时停止使用未跟踪标志: 请注意,如果您不关心切换到运行状态的WIFCONTINUED案例,则不需要WCONTINUED标志。请参阅此处的注释:我已添加了main,请告诉我在哪里执行您的解决方案,在CTR-Z之后返回shell的开头?将WUNTRACED标志添加

我正在unixshell上写东西

按下CTRL-C时,发送SIGINT信号。他在工作! 但当按下CTRL-Z时,获取信号的过程停止,但我无法返回shell。只有关闭流程,我才能返回

这是我的信号处理器:


您需要检查您孩子的状态,以查看他们何时停止使用未跟踪标志:


请注意,如果您不关心切换到运行状态的WIFCONTINUED案例,则不需要WCONTINUED标志。

请参阅此处的注释:我已添加了main,请告诉我在哪里执行您的解决方案,在CTR-Z之后返回shell的开头?将WUNTRACED标志添加到您的waitpid调用中,在调用返回后,检查WIFSTOPPEDstatus以查看子项是否已停止,而不是自动假定子项已退出。如果是这样,请为已停止的子对象执行任何您想执行的操作-可能返回提示并允许fg或bg命令继续子对象在前台或后台向其发送SIGCONT。
// in the main()
signal(SIGINT, signal_handler);
signal(SIGTSTP, signal_handler);

// when pid == 0, right over execvp()
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);

// signal handler
void signal_handler(int signum) {
  switch(signum) {
    case SIGINT:
      cout << "[caught SIGINT]" << endl;
      kill(pid, SIGINT);
      break;
    case SIGTSTP:
      cout << "[caught SIGTSTP]" << endl;
      kill(pid, SIGTSTP);
      break;
    default:
      break;
  }
}


pid_t pid; // is a global variable

 // this would be my main()
if((pid = fork()) < 0) {
        cout << "Error" << endl;
        exit(1);
    } else if(pid == 0) { // child
        setpgid(0,0);
        signal(SIGINT, SIG_DFL);
        signal(SIGTSTP, SIG_DFL);
        execvp(arguments[0], &arguments[0]);
        cout << "Argument not found" << endl;
        exit(1);
    } else if(checkIfBackground(inputNew) == false) { // mother
        int status;
        pid_t pid_r;
        if(waitpid(pid, &status, 0) < 0) { 
            cout << "Error" << endl;
        }
    } else {
        cout << "Process is in background" << endl;
    }
pid_t child = waitpid(-1, &status, WUNTRACED | WCONTINUED);
if (WIFSTOPPED(status))
    ... the child has stopped
else if (WIFCONTINUED(status))
    ... the child has been continued
else if (WIFEXITED(status))
    ... the child has exited with exit
else if (WIFSIGNALLED(status))
    ... the child exited with a signal