1

ですから、私はCを使用して基本的なUNIXシェルを作成するプロジェクトの最後にいます。プログラムのさまざまな部分を終了しましたが、今度は配管を征服したいと思います。具体的には、任意の数のパイプを処理できるプログラムを作成したいと思います。

何らかの理由で、私のコードは特定の行(ラベル:// DIES HERE)に到達してから停止し、理由がわかりません。

これが私がこれまでに持っているコードです:

//the contents of args[0] is {"ls","-l","-o"}
//the contents of args[1] is {"wc","-l"}

int pipefd[2];

pipe(&pipefd[0]);   // Error check!

fflush(stdout);
for (i = 0; i < commands; i++){
    int pid = fork();

    if (pid == 0){

        int command_no = i;
        int prev_pipe = ((command_no - 1) % 2) * 2;
        int current_pipe = (command_no % 2) * 2;
        printf("\ncmd %d: prev pipe %d, curr pipe %d\n\n", i, prev_pipe, current_pipe);
        fflush(stdout);

        // If current command is the first command, close the
        // read end, else read from the last command's pipe
        if (command_no == 0){
            close(pipefd[0]);
        }
        else{
            dup2(pipefd[prev_pipe], 0);
            close(pipefd[current_pipe]);                    
        }

        // If current command is the last command, close the
        // write end, else write to the pipe
        if (command_no == commands - 1){
            close(pipefd[current_pipe + 1]);                    
        }
        else{
            dup2(pipefd[current_pipe + 1], 1); //DIES HERE
        }
        // printf("Here?\n\n");
        execvp(*args[i], args[i]);
        fprintf(stderr, "Failed to exec: %s (%d: %s)\n", arrayOfCommands[i], errno, strerror(errno));
        _exit(1);
    }
}

どんな助けでも大歓迎です!:)

4

1 に答える 1

1

私が見る主な問題はpipe()、ループの外側にあるということです。pipe()プロセスのすべてのペアの間に新しいものが必要になります。あなたの質問へのコメントもいくつかの良い点を示しています。

私は何年も前に大学でシェルを書きました、そしてこれが私のコードからの同様のループです。今はかなり違ったやり方をしていると思いますが、それはあなたにとって役立つかもしれません:

    for (i = 0; i < iNumPipes; ++i) {
            if (i == iNumPipes - 1) {
                    /* this is the last command
                     */
                    p[1] = fdOutput;
                    p[0] = -1;
            } else if (-1 == pipe(p)) {
                    perror("pipe");
                    exit(1);
            }

            switch (iPid = fork()) {
            case -1:
                    perror("fork");
                    exit(1);
            case 0:
                    close(0);
                    dup2(fdInput, 0);
                    close(fdInput);

                    close(1);
                    dup2(p[1], 1);
                    close(p[1]);

                    if (-1 != fdErr) {
                            close(2);
                            dup2(fdErr, 2);
                            close(fdErr);
                    }

                    pc = SearchPath(pppcAvs[i][0]);
                    execve(pc, pppcAvs[i], ppcEnv);
                    perror(pc);
                    _exit(-1);
            default:
                    close(fdInput);
                    close(p[1]);
                    fdInput = p[0];
            }

    }
于 2012-09-27T01:22:39.147 に答える