次のbashコマンドは無限ループに入ります。
$ echo hi > x
$ cat x >> x
stdoutへの書き込みを開始cat
したx
後から読み続けていると推測できます。ただし、混乱を招くのは、私自身のcatのテスト実装が異なる動作を示すことです。
// mycat.c
#include <stdio.h>
int main(int argc, char **argv) {
FILE *f = fopen(argv[1], "rb");
char buf[4096];
int num_read;
while ((num_read = fread(buf, 1, 4096, f))) {
fwrite(buf, 1, num_read, stdout);
fflush(stdout);
}
return 0;
}
私が実行した場合:
$ make mycat
$ echo hi > x
$ ./mycat x >> x
ループしません。の動作cat
と、stdout
以前にフラッシュしているという事実がfread
再び呼び出されることを考えると、このCコードはサイクルで読み取りと書き込みを続けると予想されます。
これら2つの動作はどのように一貫していますか?cat
上記のコードがループしないのにループする理由を説明するメカニズムは何ですか?
cat x >> x
エラーを引き起こすアイデアが好きです。ただし、このコマンドは、演習としてKernighanとPikeのUnix本で提案されています。
cat
ほとんどの場合、stdioの代わりにシステムコールを使用します。stdioでは、プログラムがEOFnessをキャッシュしている可能性があります。4096バイトを超えるファイルで開始すると、無限ループが発生しますか?