2014-09-25 91 views
0

我試圖創建兩個子進程:çDUP未定義的錯誤

的兒童讀取一個文件,該文件被傳遞作爲參數的輸入,並寫入到輸出管道。

另一個孩子從管道讀取其輸出並將其輸出寫入一個文件,該文件也作爲參數傳入。

父級爲子級設置了一些文件描述符,並且在創建子級時,他們完成了操作描述符以滿足其需要。

但是,我遇到了設置文件描述符的問題,特別是當我嘗試關閉並複製輸入文件描述符以代替stdin時。

這裏是我的所有代碼:

#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main(int argc, char *argv[]) 
{ 
    //Open input file 
    int fdin; 
    fdin = open(argv[1], O_RDONLY); 
    //Check if opening the file was successful 
    if(fdin > 0) 
    { 
     //Open output file 
     int fdout; 
     //Create the output file and 
     //check if the output file was created 
     if((fdout = creat(argv[2], 0644)) > 0) 
     { 
      //Captures whether the dup's were successful 
      int dup_in; 
      int dup_out; 

      //Close stdin so we can replace it with our input file 
      close(0); 
      //Attempt to put the input file at position 0 
      //and check if the dup was successful 
      if((dup_in = dup(fdin)) > 0) 
      { 
       //Close stdout so we can replace it with our output file 
       close(1); 

       //Attempt to put the output file at position 1 
       //and check if the dup was successful 
       if((dup_out = dup(fdout)) > 0) 
       { 
        //Pipe success 
        int pipecreate; 
        //Pipe file descriptors 
        int pipe_fd[2]; 

        //Make the pipe and check 
        //if it was successful 
        if((pipecreate = pipe(pipe_fd)) > 0) 
        { 
         //close unneeded file descriptors 
         close(fdin); 
         close(fdout); 

         //Process id for first child 
         int cpid1; 
         //Create first child process 
         cpid1 = fork(); 

         //Process creation successful, child block 
         if(cpid1 == 0) 
         { 
          //Read pipe dup success 
          int rpipe_dup; 
          //close f_in 
          close(0); 

          rpipe_dup = dup(pipe_fd[0]); 

          //Dup successful 
          if(rpipe_dup > 0) 
          { 
           //close uneeded file descriptors 
           close(pipe_fd[0]); 
           close(pipe_fd[1]); 

           execl("count", "count", (char *) 0); 

           char readbuf[100] = {0}; 

           read(2, readbuf, 100); 
          } 
          //Dup failed 
          else 
          { 
           fprintf(stderr, "Read pipe dup failed.\n"); 
           exit(EXIT_FAILURE); 
          } 
         } 
         //Process creation successful, parent block 
         else if(cpid1 > 0) 
         { 
          //Process id for second child 
          int cpid2; 
          //Create second child process 
          cpid2 = fork(); 

          //Process creation successful, child block 
          if(cpid2 == 0) 
          { 
           //Write pipe dup success 
           int wpipe_dup; 
           //close f_out 
           close(1); 

           wpipe_dup = dup(pipe_fd[1]); 

           //Dup successful 
           if(wpipe_dup > 0) 
           { 
            //close uneeded file descriptors 
            close(pipe_fd[0]); 
            close(pipe_fd[1]); 

            execl("convert", "convert", (char *) 0); 

            char readbuf[100] = {0}; 

            write(1, readbuf, 100); 
           } 
           //Dup failed 
           else 
           { 
            fprintf(stderr, "Write pipe dup failed.\n"); 
            exit(EXIT_FAILURE); 
           } 
          } 
          //Process creation successful, parent block 
          else if(cpid2 > 0) 
          { 
           //Close unneeded file descriptors 
           close(pipe_fd[0]); 
           close(pipe_fd[1]); 

           int pid; 
           int status; 

           pid = wait(&status); 
           pid = wait(&status); 

          } 
          //Dup failed 
          else 
          { 
           fprintf(stderr, "Error creating child process 2.\n"); 
           exit(EXIT_FAILURE); 
          } 
         } 
         //Process creation unsuccessful 
         else 
         { 
          fprintf(stderr, "Error creating child process 1.\n"); 
          exit(EXIT_FAILURE); 
         } 
        } 
        //Pipe creation failed 
        else 
        { 
         fprintf(stderr, "Error creating pipe.\n"); 
         exit(EXIT_FAILURE); 
        } 
       } 
       //Dup'ing the output file descriptor failed 
       else 
       { 
        fprintf(stderr, "Error dup'ing out file descriptor.\n"); 
        exit(EXIT_FAILURE); 
       } 
      } 
      //Dup'ing the input file descriptor failed 
      else 
      { 
       //fprintf(stderr, "Error dup'ing in file descriptor.\n 
       perror("\nError dup'ing in file descriptor: "); 
       exit(EXIT_FAILURE); 
      } 
     } 
     //Creat failed 
     else 
     { 
      fprintf(stderr, "Error creating out file.\n"); 
      exit(EXIT_FAILURE); 
     } 
    } 
    //Opening input file failed 
    else 
    { 
     fprintf(stderr, "Error opening in file.\n"); 
     exit(EXIT_FAILURE); 
    } 
} 

我上編譯和運行MINIX3此。

這裏是我如何運行,包括程序輸出:

cc fork.c 
./a.out input.txt output.txt 

Error dup'ing in file descriptor: : Undefined error: 0 

任何幫助是極大的讚賞。

+1

我發現了原因。 DUP返回文件描述符,其在這種情況下是0。 如果((dup_in = DUP(fdin))> 0) 應 如果((dup_in> = DUP(fdin))> 0) – braab 2014-09-25 01:13:37

+0

如果你已經找到了你的問題的答案,發佈作爲答案,而不是評論。 – indiv 2014-09-25 01:43:13

回答

0

我發現了原因。

dup返回文件描述符編號,在這種情況下爲0. if ((dup_in = dup(fdin)) > 0)應該是if ((dup_in >= dup(fdin)))

+0

你爲什麼在那裏有'> 0'?爲什麼不只是'如果(dup_in> = dup(fdin))'? – hyde 2014-09-26 18:22:38

+0

'dup_in = dup(fdin)'和'dup_in> = dup(fdin)'顯然是非常不同的陳述,並且不能遠程替代對方。在後一種情況下,'dup()'的返回值不會被分配給'dup_in',並且會丟失。此外,您將嘗試訪問'dup_in'的值,該值在此處未初始化。或許你的意思是if((dup_in = dup(fdin))> = 0)',或者甚至更好,if((dup_in = dup(fdin))!= -1)'。 – 2014-09-26 18:30:37

+0

> 0並不意味着在那裏,當我修好它的時候,我忘了刪除它。 此外,保羅,我確實改變它if((dup_in = dup(fdin))> = 0) – braab 2014-09-26 18:45:22