Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SIGTSTP信号不停止孩子?_C++_Signals_Fork_Exec - Fatal编程技术网

C++ SIGTSTP信号不停止孩子?

C++ SIGTSTP信号不停止孩子?,c++,signals,fork,exec,C++,Signals,Fork,Exec,我试图编写一个分叉的程序,子进程执行一个命令,然后将控制权返回给父进程。我很难让SIGTSTP(C-z)信号按预期工作,不过。。。我希望父级忽略它,但子级停止并将控制权返回给父级,以便稍后可以恢复或终止子级(使用内置命令)。我将相关代码隔离到一个较小的程序中,只是为了测试它,它看起来像a)当输入C-z时,子程序不会停止,或者B)它确实停止,但不会将控制权返回给父程序(我倾向于这样做,因为当我使用cat作为stdin时,它在输入C-z后的行为不同)。这是我的密码 #include <stdi

我试图编写一个分叉的程序,子进程执行一个命令,然后将控制权返回给父进程。我很难让SIGTSTP(C-z)信号按预期工作,不过。。。我希望父级忽略它,但子级停止并将控制权返回给父级,以便稍后可以恢复或终止子级(使用内置命令)。我将相关代码隔离到一个较小的程序中,只是为了测试它,它看起来像a)当输入C-z时,子程序不会停止,或者B)它确实停止,但不会将控制权返回给父程序(我倾向于这样做,因为当我使用cat作为stdin时,它在输入C-z后的行为不同)。这是我的密码

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <cstring>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <signal.h>


int main(){
  std::cout.setf(std::ios::unitbuf);

  std::vector<std::string> vec; vec.push_back("cat");
  std::vector<char*> chvec;
  for(unsigned int i = 0; i < vec.size(); i++){
    chvec.push_back(&vec[i][0]);
  }
  chvec.push_back(NULL);
  vec.erase(vec.begin(), vec.begin() + chvec.size());

  char** argv = &chvec[0];
  signal(SIGTSTP,SIG_IGN);

  pid_t pid;
  if((pid = fork()) == 0){
    signal(SIGTSTP,SIG_DFL);
    /*pid = getpid();
    setpgid(pid,pid);*/
    std::cout << "before exec" << std::endl;
    execvp(argv[0],argv);
    perror("exec");
  }
  else{
    //setpgid(pid,pid);
    int status;
    waitpid(pid,&status,0);
    if(WIFEXITED(status) || WIFSIGNALED(status)){
      std::cout << "exited or signaled" << std::endl;
    }
    if(WIFSTOPPED(status)){
      std::cout << "process stopped" << std::endl;
    }
    //std::cout << "process exited" << std::endl;
    pause();
  }
  return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
std::cout.setf(std::ios::unitbuf);
标准:向量向量;向量推回(“cat”);
std::载体chvec;
for(无符号整数i=0;istd::cout评论中已经指出,由于
vec
向量被擦除,您需要修复未定义的行为。这是第一个问题

我看到您的代码正在使用
WIFSTOPPED
检查进程的退出状态

让我们来看看它是怎么说的:

因此,在解决了前面提到的未定义行为之后,以及在将
waitpid()
调用更改为以下内容之后,手头有了这些信息:

waitpid(pid,&status,WUNTRACED);
然后,我能够向生成的
cat
进程发送一条
kill-TSTP
消息,并获得预期结果

进程已停止

来自测试程序的消息


另外,通过扫描子进程,我可以看到子进程正在接收
TSTP
信号,并正常停止。问题只是父进程没有处理它,没有所需的
waitpid()

chvec[]
需要一个尾随的空指针。修复了这个问题(尽管这似乎对任何事情都没有影响)您可以在另一个终端窗口中使用
ps
来区分
A
B
之间的区别。如果停止子项,它将处于
T
状态。我在尝试运行您的程序时遇到分段冲突。我认为问题是您正在擦除
vec
中的所有内容。但是
chvec
contains指向那些字符串。呃..当我在另一个窗口中使用ps时,它甚至没有我的程序在列表中,只有bash和ps。这很奇怪,我的没有seg错误,并且运行命令很好(我尝试了运行良好的ls),虽然你说的很有道理。在这个小程序中,擦除是不必要的,尽管这是我正在制作的更大的程序所需要的。哦,天哪……我以前确实尝试过使用WUNTRACED,但不是等待停止信号,而是因为某种原因,cat自动停止(而不是等待C-z).我可能从我尝试过的许多其他东西中得到了一些剩余代码,这些代码把事情搞砸了,但现在可以了…非常感谢!
waitpid(pid,&status,WUNTRACED);