2016-11-05 9 views
1

複数のコマンドをパイプラインで区切って実行するシェルを作成するように頼んでいる宿題があります。ここチャイルズをフォークしてコマンドを実行するための私のコードスニペットは、次のとおりです。複数のパイプラインを実装してCでコマンドを実行

for (int i = 0; i < commands; i++) { 

     place = commandStarts[i]; 

     if((pid = fork()) < 0) exit(1); 
     else if (pid == 0) { 
      if(i < pipe_counter && dup2(fds[j + 1], 1) < 0) exit(1);// If this is not the last remaining command 

      if(j != 0 && dup2(fds[j-2], 0) < 0) exit(1);  // If this is not the first command 

      for(int c = 0; c < 2*pipe_counter; c++) close(fds[c]); 

      if(execvp(argv[place], argv+place)) exit(0);  // Execute and if it returns anything, exit! 
     } 
     j+=2; 
    } 

    for(int i = 0; i < 2 * pipe_counter; i++) close(fds[i]); 

    while ((wait(&status)) != pid);      // The only program that gets to this point is the 
             //  parent process, which should wait for completion 

、それは簡単な例ではうまく動作しているようだにもかかわらず、いくつかのより複雑で、グレーディングシステムは私にこのヒントを与える:あなたがすべきプロンプトを表示する前にパイプチェーン内のすべてのプロセスが終了するのを待ってください。

私の間違いはどこですか?

+0

ここで、各プロセスが完了するのを待つコードはどこですか? – wallyk

+0

スニペットの最後でわかるように、ループ中にすべてのプロセスが完了するのを待っています! –

+0

あなたは?どうしたの?...まったく。私はあなたが思うようにそれが動作するとは思わない。 – wallyk

答えて

1

私が間違っていたのは、最後のフォークされた子のみが終了するのを待っていたことでした。私はを介してこれを考える助けるためwallyk

for (int i = 0; i < commands; i++) { 

     place = commandStarts[i]; 

     if((pid = fork()) < 0) exit(1); 
     else if (pid == 0) { 
      if(i < pipe_counter && dup2(fds[j + 1], 1) < 0) exit(1);// If this is not the last remaining command 

      if(j != 0 && dup2(fds[j-2], 0) < 0) exit(1);   // If this is not the first command 

      for(int c = 0; c < 2*pipe_counter; c++) close(fds[c]); 

      if(execvp(argv[place], argv+place)) exit(1);   // Execute and if it returns anything, exit! 
     } 
     j+=2; 
    } 

    for(int i = 0; i < 2 * pipe_counter; i++) close(fds[i]); 

    for(int i = 0; i < commands; i++) wait(&status);   // The only program that gets to this point is the 
                   //  parent process, which should wait for completion. 

また、多くの感謝:

はここで終了することすべての子を待って、正しいコードスニペットです!

+0

これは堅牢な実装に非常に近いものですが、wait()によって刈り取られる孫が脱線するという欠点があります。子供のpidが生成されたものとして追跡でき、待機ループがそれらの特定のIDを待つことができます。 – wallyk

関連する問題