0

ifをdup2チェックした後に使用する理由を説明してください。それは素晴らしいでしょう。fd[0] != STDIN_FILENOfd[0] != STDIN_FILENOdup2STDIN_FILENO

int fd[2];
pid_t pid;

if(argc != 2) {
        fprintf(stderr, "Must be specify exactly 1 file\n");
        exit(0);
    }

    if(pipe(fd) < 0)
        exit(1);./ 

    pid = fork();

    switch (pid) {
        case -1:
            exit(1);
        case 0:
            close(fd[1]);
                        //here
            if(fd[0] != STDIN_FILENO) {
                if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
                    exit(3);
                close(fd[0]);
            }
            if(execlp("tr", "tr", "[a-z]", "[A-Z]", (char *) 0) < 0)
                exit(4);
            break;

        default:
            close(fd[0]);
                        // and here
            if(fd[1] != STDIN_FILENO) {
                if(dup2(fd[1], STDIN_FILENO) != STDIN_FILENO)
                    exit(5);
                close(fd[1]);
            }
            if(execlp("cat", "cat", argv[1], (char *) 0) < 0)
                exit(4);
            break;
    }
    return 0;
4

4 に答える 4

3

その意図は、stdin (STDIN_FILENO、これは 0) が fd[0] が指すファイル (パイプの読み取り側) を指すようにすることです。最初にそれらがまだ同じではないことを確認してください...同じである場合、コードは0を0に複製してから0を閉じます-良くありません。それらが同じでない場合は、dup2 を使用して、STDIN_FILENO が fd[0] が指す場所を指すようにします。dup2 が成功すると、2 番目の引数が返されるため、dup2 が失敗した場合は exit を呼び出してチェックが行われます。

あなたが書く

私が理解していることから、 fd[0] != STDIN_FILENO は失敗します

なぜあなたがこれを「理解」したのかは、まったく明らかではありません。fd[0] に STDIN_FILENO (つまり 0) が含まれている場合にのみ失敗しますが、pipe呼び出しによって割り当てられたファイル記述子が含まれているため、失敗する可能性は低くなります。

dup2 は STDIN_FILENO 以外の値を返します。

dup2 は、成功すると 2 番目の引数を返します。失敗しない限り、STDIN_FILENO 以外のものは返されません。-- その場合は -1 を返します。

于 2013-03-28T09:06:57.383 に答える
1

呼び出しを行う前に標準入力と標準出力が両方とも閉じられていた場合は、2 つの記述子がパイプに割り当てられfd[0] != STDIN_FILENOますが、通常は標準入力と標準出力が以前に開いているため、チェックは防御的なプログラミング手法です (パイプがパイプの両端に使用されるファイル記述子は、次に小さい番号の記述子です)。pipe()pipe()

于 2013-03-28T09:23:04.287 に答える
1

execlp基本的にプログラムを実行します。そのプログラムはSTDIN_FILENO(つまり、fd 0) から入力を読み取ります。およびsyscall は、 または ファイル記述子をその番号に移動するために使用さdup2れます。closefd[0]fd[1]

于 2013-03-28T08:58:56.790 に答える
0

このプログラムは、親プロセスで cat を実行し、子プロセスで tr を実行し、cat の出力を tr に読み取らせます。

最初にパイプを開き、親が fd[1] に書き込み、子が fd[0] から読み取ることで、親が子にデータを書き込むことができます。

親では、fd[1] を stdin に複製します。子では、fd[0] を標準入力に複製します。

子では、tr を実行する execlp で、tr は stdin から読み取ります。stdin は fd[0] として複製されているため、実際にはパイプからの cat の出力を読み取ります。

execlp()現在のプロセスで新しい実行可能ファイルを実行します。man execlp引数の詳細については、こちらを参照してください。

于 2013-03-28T08:57:01.697 に答える