不知道怎么理解这句话,原文写着:当system创建的子进程结束时,system的调用者可能错误的认为,它自己的一个子进程结束了。于是,调用者将会调用wait函数以返回子进程的终止状态,这样就阻止了system函数获得子进程的终止状态,并将其作为它的返回值。
     不理解的地方有亮点:1 实际书中的代码system函数创建的子进程也是system调用者的子进程,也就是说system 函数所在的进程和调用system函数的进程是同一个进程 2 即使两者不在一个进程中,一个进程也无法阻止另外一个进程获取子进程的终止状态
请高手解惑
原文代码如下:#include "apue.h"
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
static void sig_int(int signo){
    printf("caught SIGINT\n");
}static void sig_chld(int signo){
    printf("caught SIGCHLD\n");
}int system(const char *cmdString){
    pid_t pid;
    int status;
   
    if(cmdString == NULL)
        return (1);    if((pid=fork())<0){
        status=-1;
    }else if(pid==0){
         execl("/bin/sh","sh","-c",cmdString,(char*)0);
        _exit(127);
    }else{
        while(waitpid(pid,&status,0)<0){
            if(errno!=EINTR){
                status=-1;
                break;
            }
        }
       
        
    } 
  
    return status;
}
/*
 * 
 */
int main(void) {    pid_t pid;
    int status;
    
    if(signal(SIGINT,sig_int)==SIG_ERR){
        err_sys("signal(SIGINT) error");
    }
    if(signal(SIGCHLD,sig_chld)==SIG_ERR){
        err_sys("signal(SIGCHLD) error");
    }
  
    
    if(system("/bin/ed")<0){
        err_sys("system() error");
    }
    return 0;
}

解决方案 »

  1.   

    system()执行命令的方式是fork一个子进程, 父进程其实就是调用system的进程.
    由于system需要知道子进程(shell命令)的返回状态码, 所以必须要由system中的waitpid进行回收,
    如果你注册了SIGCHLD的信号处理函数, 那么信号处理函数可能会先于 system函数中waitpid执行,
    如果你在信号处理函数中也用waitpid获取子进程结束状态, 那么随后system函数中waitpid函数就会返回失败,
    你会从errno获取到一个 No child processes的错误提示.所以阻塞SIGCHLD的最终目的就是要system函数中的waitpid先执行, 否则出现上面的(少数)情况, system返回-1,
    你可能就会认为shell命令执行失败了.