分叉多个子进程并打开()/ dup2()

时间:2017-11-30 07:47:22

标签: c fork file-descriptor dup2

所以我试图读取包含多个命令的行,并为每个命令创建一个子进程来处理它。一旦我尝试取消注释 stdout重定向if(fd2)语句,我就遇到了麻烦。它不是出现一次所需的输出,而是出现多次。我不确定是什么导致这种情况,我关闭所有文件描述符并让孩子退​​出。

我正在处理的命令可能同时具有stdout和stdin重定向,并且我成功设置了stdin的重定向,但我似乎无法找到我的bug。我没有收到perror()警告。这不是dup2()的问题,而是open()的问题,如果我只是取消注释该部分,我会收到错误。

int concCmd(Cmd cmdM[], int iCmdCnt, Token tokenM[], int iTokenCnt){
   long pid, wpid;
   int i, status=0, fd = 0, fd2=0;
   fflush(0);
   for(i=0; i<iCmdCnt; i++){ //create a process for every command
        pid=fork();
        switch(pid){
            case -1:
                perror("Fork\n");
                return 1;
            case 0:
                if(cmdM[i].iStdinRedirectIdx != 0){ //does command need stdin redirection
                    if((fd = open(tokenM[cmdM[i].iStdinRedirectIdx], O_RDONLY)) <0){
                        perror("open stdin");
                        return 1;
                    }
                    if((dup2(fd,STDIN_FILENO))<0){
                        perror("dup2");
                        return 1;
                    }
                    close(fd); //close in parent process
                }
                if(cmdM[i].iStdoutRedirectIdx != 0){ //command needs stdout redirection
                //   if((fd2 = open(tokenM[cmdM[i].iStdoutRedirectIdx], O_WRONLY|O_CREAT|O_EXCL)) < 0){
                //        perror("open stdout");
                //        return 1;
                //    }
                //    if((dup2(fd, STDOUT_FILENO))<0){
                //        perror("dup2");
                //        return 1;
                //    }
                    close(fd2);
                }
                //EXECVP HERE!!!
                //execvp (cmdM[i].szCmdNm, tokenM[
                exit(0);
            default:
                wpid = wait(&status);
                close(fd);
                close(fd2);
                fprintf(stderr, "%ld %ld\n", (long)getpid(), wpid);
        }
    }
    return 0;
}

我在开始分叉之前添加了一个fflush(0),以清除缓冲区,如另一个问题所示,这应该合理地清除缓冲区,当我为stdout调用open时,但我仍然得到了同样的错误。

1 个答案:

答案 0 :(得分:0)

我打算发表评论,因为我想说的很简单,但我需要引用一些代码,所以也许发布答案更容易。

{
"Status":"OK",
"Series":[
{"ColorCode":"GREEN","ColorVal":40.5},
{"ColorCode":"RED","ColorVal":12.8},
{"ColorCode":"YELLOW","ColorVal":12.8}
]
}

在您的代码中,您在问题中发表评论的关于 // if((fd2 = open(tokenM[cmdM[i].iStdoutRedirectIdx], O_WRONLY|O_CREAT|O_EXCL)) < 0){ // perror("open stdout"); // return 1; // } // if((dup2(fd, STDOUT_FILENO))<0){ // perror("dup2"); // return 1; // } 的部分有拼写错误。

fd2应为dup2(fd, STDOUT_FILENO)

我不知道您的源代码中是否真的是一个拼写错误,或者您在发布问题时犯了错误。