1

So I'm trying to read a line with multiple commands and creating a child process for each command to handle it. I'm having some trouble once I try to uncomment the if(fd2) statement for stdout redirection. Instead of the desired output appearing once, it appears multiple times. I'm not exactly sure what is causing this, I'm closing all of the file descriptors and having the child exit.

The commands I'm dealing with may have both stdout and stdin redirection, and I'm successful in setting up the redirection for stdin, but I cant seem to find my bug. I don't get a perror() warning on display. It's not so much as a problem with dup2(), but rather with open(), if I just uncomment that part I get the error.

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;
}

I went ahead an added a fflush(0) before I started forking, to clear out the buffer, as suggested in another question, which should reasonably clear the buffer for when I call open for stdout, but I still get the same errors.

JOhAnn4187
  • 77
  • 1
  • 10
  • Possible duplicate of [printf anomaly after "fork()"](https://stackoverflow.com/questions/2530663/printf-anomaly-after-fork) – Alex Hoppus Nov 30 '17 at 07:59
  • You should give a [mcve]. I cannot reproduce any problem once I have replaced the (here incomplete) `execvp` and of course removed the `printf("*STDOUT");` that would go to the redirected file – Serge Ballesta Nov 30 '17 at 11:30
  • @AlexHoppus I went ahead and added a `fflush(0)` as suggested in the question. However that did not resolve my initial problem. – JOhAnn4187 Nov 30 '17 at 16:19

1 Answers1

0

I was going to make a comment, because what I want to say is very simple, but I need to reference some code, so maybe posting an answer is easier.

        //   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;
        //    }

In your code, the part about fd2 which you comment in your question has a typo.

dup2(fd, STDOUT_FILENO) should be dup2(fd2, STDOUT_FILENO)

I don't know whether it is really a typo in your source code, or you just made a mistake when you posting your question.

Bruce
  • 523
  • 5
  • 8