1

以下は私がそれを機能させようとしているコードです...

私は出力を期待していました

OUTPUT from PipeAttempt(args1, args2)

に続く

I am here

OUTPUT from PipeAttempt(args3, args4)

しかし実際には、PipeAttempt(args1、args2)からの出力しか得られません。

プログラムは私からの入力を待ちます。Enterキーを押すと、プログラムは終了します。

ここで何が欠けているのか教えていただけますか?

int main () {
    char* args1 [] = {"/usr/bin/head", "/etc/passwd", NULL};
    char* args2 [] = {"/bin/sort", NULL};

    char* args3 [] = {"/bin/cat", "piped.input", NULL}; 
    char* args4 [] = {"/usr/bin/wc", NULL};



    PipeAttempt(args1, args2);

    printf("I am here\n");

    PipeAttempt(args3, args4);


    return 0;

}


void PipeAttempt(char* args1[], char* args2[]) {
    int pfildes[2]; <br>
    pid_t cpid1, cpid2; <br>
    char *envp[] = { NULL };<br>


    if (pipe(pfildes) == -1)    {perror("demo1"); exit(1);}
    if ((cpid1 = fork()) == -1)   {perror("demo2"); exit(1);}
    else if (cpid1 == 0) {        /* child:  "cat a"                      */
          close(pfildes[0]);    /* close read end of pipe               */
          dup2(pfildes[1],1);   /* make 1 same as write-to end of pipe  */
          close(pfildes[1]);    /* close excess fildes                  */

       execve(args1[0], args1, envp);

          perror("demo3");       /* still around?  exec failed           */
          exit(1);             /* no flush                             */ 
        }
    else {                      /* parent:  "/usr/bin/wc"               */
          close(pfildes[1]);    /* close write end of pipe              */
          dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
          close(pfildes[0]);    /* close excess fildes                  */

       execve(args2[0], args2, envp);
          perror("demo4");       /* still around?  exec failed           */
          exit(1);          /* parent flushes                       */
        }   
}
4

2 に答える 2

1

元の親はexec呼び出しによって上書きされたため、/ usr / bin / head / etc /passwd|の出力しか取得できませんでした。/ bin / sortで、/ bin / cat piped.input | / usr / bin/wcの出力を取得できませんでした。

プログラムは実際にはキーボード入力を待っていませんでした。何が起こったのかというと、シェルプロンプトが表示されなかったということです。親が子の前に終了し、プロンプトがシェル(親を待機している)によってすぐに表示され、その後に子からの出力が表示されたため、プログラムがユーザー入力を待っています。

これを解決するために、関数内で別の子をフォークすることができます。これにより、各関数(PipeAttempt)の呼び出しに対して、2つの子がパイプを処理し、主に4つの子すべてが完了するのを待って、親が最後に終了するようになります。シェルプロンプトが返されます。以下の変更されたコードを考えると、plの下にあります。コンパイルする前に、wait、strlenなどのヘッダーファイルをインクルードします。これでクエリが解決することを願っています。

void PipeAttempt(char* args1[], char* args2[]) ;
int main () {
int i;
char* args1 [] = {"/usr/bin/head", "/etc/passwd", NULL};
char* args2 [] = {"/bin/sort", NULL};

char* args3 [] = {"/bin/cat", "piped.input", NULL}; 
char* args4 [] = {"/usr/bin/wc", NULL};

PipeAttempt(args1, args2);
write(1, "I am here\n", strlen("I am here\n"));
PipeAttempt(args3, args4);
for (i=0; i < 4; i++)
{

    wait(NULL);
}
return 0;
}

void PipeAttempt(char* args1[], char* args2[]) 
{
    int pfildes[2]; 
    pid_t cpid1, cpid2; 
    char *envp[] = { NULL };


    if (pipe(pfildes) == -1)    {perror("demo1"); exit(1);}

    if ((cpid1 = fork()) == -1)   {perror("demo2"); exit(1);}
    else if (cpid1 == 0)
   {        /* child1    */
        close(pfildes[0]);    /* close read end of pipe               */
        dup2(pfildes[1],1);   /* make 1 same as write-to end of pipe  */
        close(pfildes[1]);    /* close excess fildes                  */
        execve(args1[0], args1, envp);
        perror("demo3");       /* still around?  exec failed           */
        exit(1);             /* no flush                             */ 
    }
   else {                      
    /* child2:  "/usr/bin/wc"               */
     if (0==fork())
      {
         close(pfildes[1]);    /* close write end of pipe              */
         dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
         close(pfildes[0]);    /* close excess fildes                  */
         execve(args2[0], args2, envp);
         perror("demo4");       /* still around?  */
         exit(1);
      }
//Parent
 close(pfildes[0]); 
 close(pfildes[1]); 
    }   
}
于 2012-07-15T19:11:37.657 に答える
0

PipeAttempt()関数はfork / execを実行します-それがメイン関数に戻ることをどのように期待できますか?

于 2012-07-15T17:43:48.027 に答える