我正在尝试从stdin
读取并输出数据,但事情是有效的,除了它没有输出新的传入数据。我不太确定问题出在哪里。我猜测确定stdin
大小时有一些事情要做。任何帮助将不胜感激!感谢
tail -f file | my_prog
#include <stdio.h>
#include <sys/stat.h>
long size(FILE *st_in) {
struct stat st;
if (fstat(fileno(st_in), &st) == 0)
return st.st_size;
return -1;
}
int main (){
FILE *file = stdin;
char line [ 128 ];
while ( fgets ( line, sizeof line, file ) != NULL )
fputs ( line, stdout ); /* write the line */
long s1, s2;
s1 = size(file);
for (;;) {
s2 = size (file);
if (s2 != s1) {
if (!fseek (file, s1, SEEK_SET)) {
while ( fgets ( line, sizeof line, file ) != NULL ) {
fputs ( line, stdout ); /* write the line */
}
}
s1 = s2;
usleep(300000);
}
}
return 0;
}
修改:已修复!
答案 0 :(得分:1)
在FILE *
达到EOF后,它会保持在不再读取数据的状态,直到您使用clearerr()
或fseek()
清除'EOF'位。但是,如果标准输入连接到终端,那么这不是可搜索设备,因此它不会清除错误,它可能没有做任何有用的事情:
POSIX说:
fseek()在无法寻找的设备上的行为是实现定义的。
您的循环输入条件是可疑的;你需要在开始之前睡觉,并且你需要在每次迭代时睡觉。实际上,通常你写tail -f
而不用担心文件大小;你睡觉,尝试阅读直到下一个'EOF',重置文件EOF指示器,然后重复。另请注意,未定义管道或终端的大小。
另外,为函数FILE *
调用filename
参数是常规的;它有完全错误的含义。文件名是一个字符串。
答案 1 :(得分:0)
这不是真正的标准C:
size(file);
调用stat()获取文件信息 - 文件的组织类型,文件大小和权限。
你的代码所做的是最终将文件指针设置为文件的末尾,因为它试图通读它。考虑使用stat()(或打开文件上的fstat())。
rewind()将文件指针重置为文件的开头,fseek()会将它放在你需要的任何地方。
tail -f在EOF点重复尝试文件,在两次尝试之间短暂睡眠....它不会“认为”EOF是一个错误。它会记住EOF的当前文件偏移量,然后使用SEEK_END调用fseeks(),然后调用ftell(),并比较偏移量。如果存在差异,则将fseek() - s返回到最后一个已知端点并读取数据。
此描述来自旧的unix源。我确信从那以后它已经被调整过了。