中断调用函数popen的进程

时间:2016-12-29 16:58:38

标签: c process signals fork alarm

我需要实现一个执行文件并发送执行结果的子进程,2进程将与共享内存段通信。

我的问题是我要在10秒后杀死调用popen的子进程,但函数popen会忽略信号。

这是我的代码(不包括共享内存段):

void kill_child(int sig)
{
 kill(child_pid,SIGKILL);
printf("processus killed \n");

}

/*code....*/

signal(SIGALRM,(void (*)(int))kill_child);

if(fork()==0){
                res.buffer=true;
                FILE * fd;
                char cmd[BUFFER_SIZE],output[BUFFER_SIZE];
                strcpy(cmd,"./");
                strcat(cmd,res.filepath);
                system(cmd);
                if((fd=popen(cmd,"r"))== NULL)
                    exit(1);
                else 
                    res.status=200;


                strcpy(output,"");
                while(fgets(buf,sizeof(buf)-1,fd))
                    strcat(output,buf);

                if(pclose(fd))
                    exit(1);

                strcat(res.customHTML,output);
                res.buffer=true;


                int err = sendResponse(res,args->client_fd);
                if (err < 0) on_error("failed!\r\n");



                exit(0);


 } 

 else{

               int status;
               alarm(10);
               waitpid(-1,&status,0);
               printf("status %d _n);
}

如何让孩子的过程可以中断?

谢谢

1 个答案:

答案 0 :(得分:1)

首先,您需要将子PID实际存储到child_pid中。它从fork返回父进程,因此将fork调用更改为

child_pid = fork();
if(child_pid == 0)
  {
...

否则你的杀戮被传递一个随机值。幸运的是,它似乎默认为0,杀死意味着杀死同一进程组中的所有进程,因此您的子进程被杀死。

其次,不是调用popen()自己用(例如)execvp()调用可执行文件,让父母使用你自己创建的管道读取输出...

int fds[2];

pipe(fds);
child_pid = fork();
if(child_pid == 0)
  {
  char *cmd[]={"mycmd",NULL};

  /* Replace stdout with the output of the pipe and close the original */
  dup2(fds[1],1);
  close(fds[0]);
  close(fds[1]);
  execvp(cmd[0],cmd);
  }
else
  {
  close(fds[1]);
  alarm(10);
  while(...)
     {
     read(fds[0],....);
     if(waitpid(child_pid,&status,WNOHANG))
         {
         ....
         }
     }
  }

通过这种方式,您只运行了一个运行可执行文件的子进程,并且您可以了解它何时以及如何退出。