ファイル記述子にEOFを発行する方法(開いたまま)

ファイル記述子にEOFを発行する方法(開いたまま)

端末で+を押すのとCtrl同様の動作を達成するために、私のプログラムでどのコードを呼び出すことができますか?Dつまり、readSTDINで呼び出された関数を子プロセスから返し、0親プロセスでこの「STDIN」ファイル記述子を閉じたくないのですか?

EOF条件がLinuxのプロセスにどのように渡されるかを理解しようとしています。

readリターンは単なる勧告であるように見え、0実際には、これらのEOF状況が発生した後でも読み続けることができます。次のプログラムを検討してください。

#include <unistd.h>
#include <stdio.h>

void terminate_buf(char *buf, ssize_t len)
{
    if(len > 0) {
        buf[len-1] = '\0';
    } else {
        buf[0] = '\0';
    }
}

int main()
{
    int r;
    char buf[1024];

    while(1) {
        r = read(0, buf, 1024);
        terminate_buf(buf, r);
        printf("read %d bytes: %s\n", r, buf);
    }

    return 0;
}

プログラムをコンパイルし(gcc -o reader reader.creader.cと仮定)、端末でプログラムを実行し、Ctrl+を押しDてEnterを押すと、foobarEnter次の内容が表示されます。

$ ./reader 
read 0 bytes: 
foobar
read 7 bytes: foobar


EOFイベント後に意味のあるデータを読み取ることが完全に可能であることを示します。 1行で+を数回押してCtrlから、いくつかのテキストをタップして何も起こらなかったかのようにデータを読み続けることができます(+を押すたびに「read 0 bytes:」が印刷されます)。ファイル記述子は開いたままです。DreaderCtrlD

では、ここで何が起こっているのか、この動作をどのように複製できますか? EOFを見た後、子プロセスにいくつかのデータを表示させる方法は?一般ファイルI / O(またはs)を使用してioctlこれを行う方法はありますか?それともptyを開く必要がありますか?回数がゼロの通話はwrite機能しないようで、read相手が応答しません。何はい本当ですか?

答え1

Ctrl-D(0x04)は、端末デバイスによってEOFにマッピングされます。パイプやファイルから読み込む場合、これは発生しません。

echo -e "a\x04b" | cat

または

echo -e "a\x04b" | hd

たとえば、パイプラインの最初のプログラムが端末からデータを読み込んでいて、マッピングされたEOFを無視したい場合は、端末の動作を変更できます。

stty eof -

そしてCtrl-Dはもう機能しません。または、次のように全体の行規則を変更できます。

stty raw

ファイルのように読み取ることができ、変換は必要ありません。

EOF文字が含まれていない限り、EOF文字を使用して複数のファイルを送信できます。一人の人がそれをします。

ただし、MIMEマルチパート、zmodem、またはパイプにアーカイブなどの確立されたソリューションを使用する方が良いかもしれません(たとえば、2番目のものは最初のtarアーカイブのファイルをリストします)tar cf - *txt | tar tf -

答え2

問題は、実際には「EOF条件」のようなものがないことです。通常、ゼロを返す読み取りはファイルの終わりとして解釈されますが、見てわかるように読み続けることができます。追加の読み取りは再びゼロを返す可能性があり、他のプロセスが同時にファイルに書き込む場合はより多くのデータを返すことができます。

端末の信号にもCtrl-D特別な「EOF」信号属性はありません。実際に行うことはEnterキーを押すのと同じですが、改行文字を追加せずに現在の行をプロセスに返すことです。行(つまり、空行)の最初の入力としてCtrl-Dを押すと、ゼロ文字が返され、これは慣例に従って「EOF」と解釈されます。

読み取りの戻り値 0 の解釈方法は、読み取りシステム呼び出しを呼び出すプロセスによって決まります。

関連情報