0

ターミナルでの「ls -l | tail -n 2」呼び出しをシミュレートする簡単なプログラムを作成しようとしています。そのために「fork」と「execvp」を使用しています。さて、ここにコードがあります:

int main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t child1;
    pid_t child2;
    char* com1[] = {"ls", "-l",NULL};
    char* com2[] = {"tail", "-n","2",NULL};

    if (!(child1 = fork())) 
    { 
       close(STDOUT);
       dup(pipefd[1]); 
       close(pipefd[1]); 
       execvp (com1[0], com1);
       _exit(EXIT_SUCCESS);
    }
    else
    {
        close(pipefd[1]);
        if (!(child2 = fork())) 
        { 
            close(STDIN);
            dup(pipefd[0]); /* dupWR now holds the lowest fd available, meaning STDOUT's */
            perror("dup 2");
            close(pipefd[0]); /* reader will see EOF */
            execvp (com2[0], com2);
            _exit(EXIT_SUCCESS);
        }
        else
        {
            close(pipefd[0]);
            waitpid(child2,0,0);
        }
        waitpid(child1,0,0);
    }


    return 0;
}

次のエラーが表示されます。

dup 2: Bad file descriptor
tail: cannot fstat `standard input': Bad file descriptor
tail: -: Bad file descriptor

同期に問題があるようです。実際、次のように宣言すると: com2[] = {"ls", "-l",NULL}; 正常に動作します(つまり、通常のシェルと同じです)。さらに、2 番目の「fork」の 2 番目の「dup」がエラーを返すことがわかりました。何故ですか?このコードのどこに問題があるのか​​ わかりません。助けてください!

編集:このコードを追加しました(パイプを作成するのを忘れました):

if (pipe(pipefd) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
}

ありがとう、役に立たない!

4

1 に答える 1

1
close(STDOUT);
dup(pipefd[1]); 
close(pipefd[1]); 

dup 新しいファイル記述子を返し、戻り値を使用しないため、破棄しています。

そのように、代わりに標準出力を置き換えたかったですか?

dup2(pipefd[1], STDOUT_FILENO);

もしそうpipefd[]なら、本当に最初に初期化する必要があります。pipeどこかに電話するつもりだったの?

于 2013-05-19T22:25:24.997 に答える