2

同様の質問がすでに出されていることは知っていますが、どの回答も役に立ちませんでした。ミニチュアLinuxシェルを実装しようとしていますが、複数のパイプでスタックしています。単一のパイプ(例ls | wc)を使用したコマンドは機能しますが、2つ目のパイプを追加すると、コンソールに何も表示されません。これが私のコードです。

void ExecuteCommand(NODE *cHead,NODE *oHead)
{
    int fd[10][2];  // file descriptors' array
    int nfdCnt = 0 ;    // file descriptors counter
    string strCmd;      // command
    string strOp = "";  // operator
    int nOpCnt = 0 ;    // operator count

    while(1)
    {
        if (cHead != NULL)  // cHead is head pointer to the linked list of commands.
        {
            strCmd =  GetCmdOROperator(&cHead); // get command
        }
        if (oHead == NULL)  // oHead is head pointer to the linked list of operators.
        {
            strOp = "";
        }
        else
        {
            strOp = GetCmdOROperator(&oHead);   // get operator
        }

        if (strOp.empty())  // no operator exists. single or last command in the chain.
        {
            // Fork the child process
            pid_t child_id = fork();

            if(child_id == 0)
            {
                // Execute the command

                if (nOpCnt) // if we previously encountered any operator
                {
                    close(fd[nfdCnt-1][FD_WRITE]);
                    dup2(fd[nfdCnt-1][FD_READ], FD_READ);   // read from pipe updated by previous command
                }

                // call execvp()

                exit(-1);
            }
            else
            {
                for (int i = 0 ; i < nfdCnt; i++)
                {
                    close(fd[nfdCnt][0]);
                    close(fd[nfdCnt][1]);
                }
                wait(NULL);
                break;
            }
        }

        if (strOp == "|")
        {
            nOpCnt++ ;

            if (pipe (fd[nfdCnt]) < 0)
            {
                printf("\npipe error");
                return ;
            }

            pid_t child_id = fork();
            if (child_id == 0)
            {
                close(fd[nfdCnt][FD_READ]); // we dont need this
                dup2(fd[nfdCnt][FD_WRITE], FD_WRITE);

                if(nOpCnt > 1) // if we have already encountered a pipe before
                {
                    dup2(fd[nfdCnt-1][FD_READ],FD_READ);
                    close(fd[nfdCnt-1][FD_WRITE]);
                }

                // call execvp()
                exit (-1);
            }
            else
            {
                nfdCnt++;
            }

        }

    }
}
4

2 に答える 2

2

私はあなたのコードをあまり詳しく調べていませんが、ファイル記述子を開いたままにしているようです。その場合、あなたがコードを閉じたと思っていても、誰かが書き込み側を開いているため、プロセスは読み取りをブロックします。各dup2の後にクローズを追加してみてください。

 dup2( fd[ nfdCnt - 1 ][ FD_READ ], FD_READ );
 close( fd[ nfdCnt - 1 ][ FD_READ ])

(また、エラーチェックを追加します。、、、 dup2などforkcloseすべて失敗する可能性があります。フォーラムに質問を投稿するときにエラーチェックをスキップすると便利な場合がありますが、実際のコードでは省略しないでください。)

于 2012-09-08T17:57:03.163 に答える
1

これ

 if (strOp == "|")

Cでは機能しません。strcmp文字列を比較するために使用します。または、質問CをC ++ではなくCと間違えた可能性がありますか?どの言語コンパイラを使用していますか?

于 2012-09-08T18:13:20.507 に答える