以下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代码可以继续在一个周期中进行读写。
这两种行为如何保持一致?什么机制解释了为什么cat
上面的代码没有循环?
cat x >> x
会导致错误的想法;但是,此命令在Kernighan和Pike的Unix书中建议作为练习。
cat
最有可能使用系统调用而不是stdio。使用stdio,您的程序可能正在缓存EOFness。如果从大于4096字节的文件开始,是否会遇到无限循环?