2

これは大きなプログラムのほんの一部ですが、execvpから出力を取得しようとしていますが、execvpを正しく設定しdup2て、パイプに転送しています。私の問題は、パイプの全長を読み取るために読み取りを使用する場合にexecvp発生します。毎回の出力の大きさはわかりません。入力によって異なる可能性があるためです。

    int fd[2];
    pipe(fd);
    pid_t pid = fork();
    if (pid == 0) {
        close(fd[0]);
        dup2(fd[1], 1);
        execvp(msg.v,(char *[]){msg.v,NULL});
    } else if (pid > 0) {
        close(fd[1]);
        read(fd[0],msg.v,....);
    }

読み取り用にいくつかの異なるサイズを試しましたが、それだけでは不十分であるか、最後にランダムなジャンクが発生します。stdioからpopenやその他のいくつかのものを使用できることはわかっていますが、割り当てにはそれらを使用しない必要があります。出力を取得するための他の方法のブランキング。

プログラム全体がサーバーの一部である、もう少し役に立たない情報。サーバーとクライアントを作成しています。サーバーを起動して、INETストリームを介してサーバーに送信するターミナルコマンドをクライアントに提供し、出力をクライアントに返送して、すべてstdioなしで出力を表示します。

4

2 に答える 2

1

readバッファに返されるデータの量に注意する必要があります。readが正の数を返している間、より多くのデータがあります。プログラムが完了すると、その終わりが閉じられ、pipeあなたreadはに戻り0ます。

} else if (pid > 0) {
    close(fd[1]);
    ssize_t r = read(fd[0],buf,bufsz);
    if (r > 0) do {
        /* ... do something with r bytes in buf */
        r = read(fd[0],buf,bufsz);
    } while (r > 0);
    if (r < 0) {
        perror("read");
        /*...*/
    }
}

read「システムコールの中断」エラーが表示された場合は、cafが言及したケースが発生していますEINTRreadその場合は、再起動します。

        for (;;) {
            r = read(fd[0],buf,bufsz);
            if (r != -1 || errno != EINTR) break;
        }

非ブロッキングI/Oを実行していないと想定しているため、「リソースが一時的に利用できません」というメッセージは表示されません。

于 2012-08-07T01:36:25.610 に答える
1

EOF を示す returnまで読み続けread()ます(または、または以外の永久エラーに設定された0-1 )。errnoEAGAINEINTR

の戻り値を無視してはなりませんread()。これは、返されたバイト数を示しています。そのため、バッファの最後に「ジャンク」が表示されます。これらの場合、read()バッファ全体が満たされておらず、戻り値を無視したため、実際にどれだけ返されたかわかりません。

于 2012-08-07T01:37:52.010 に答える