我有一个程序要检查文件是否已被修改。 regtest失败,事实上,尽管文件已经更改,但st_mtime
还没有!此外,外部统计也证实了这一点。
我相信st_mtime 应更改,因为stat(2)表示
字段st_mtime由文件修改更改,例如,mknod(2),truncate(2),utime(2)和write(2)(大于零字节)。
这里有一些C代码说明了这个问题:
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void touch(const char *fn, const char *contents)
{
FILE *fp;
assert(fp = fopen(fn, "w"));
fprintf(fp, contents);
fclose(fp);
}
int main( int argc, char *argv[] )
{
struct stat st;
char path[] = "/tmp/foo";
time_t m1, m2;
unsigned int t;
touch(path, "hello\n");
assert(!stat(path, &st));
m1 = st.st_mtime;
touch(path, "hello, world!\n");
t = sleep(2);
assert(!stat(path, &st));
m2 = st.st_mtime;
printf("Sleep remaining: %lu\n", t);
printf("Elapsed modtime=%lu\n", m2 - m1);
}
这是为bash提供的东西,以确认它不仅仅是在C程序中缓存:
$ while true;做stat / tmp / foo | grep修改;睡1;完成
有什么建议吗? Fwiw,这是在如此确定的系统上运行的:
jeff@london:src $ uname -a
Linux london 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:32:42 UTC 2011 x86_64 GNU/Linux
jeff@london:src $
答案 0 :(得分:4)
首先,我强烈建议您不要在assert
内使用带副作用的陈述。我理解它很方便,如果代码永远不会生产,那真的不重要,但它不是好形式。特别是,如果您定义NDEBUG
,assert
将转换为noop,则不会执行条件的代码。
现在,问题很可能是您在sleep
次调用之后调用touch
调用,而不是在它们之间。改变这个:
touch(path, "hello\n");
assert(!stat(path, &st));
m1 = st.st_mtime;
touch(path, "hello, world!\n");
t = sleep(2);
assert(!stat(path, &st));
m2 = st.st_mtime;
到
touch(path, "hello\n");
int rv = stat(path, &st);
assert(!rv);
m1 = st.st_mtime;
t = sleep(2);
touch(path, "hello, world!\n");
int rv = stat(path, &st);
assert(!rv);
m2 = st.st_mtime;
答案 1 :(得分:1)
永远不要在有副作用的函数上使用assert
!
始终这样做:
FILE * fp;
fp = fopen(...);
assert(fp != NULL);
包含assert()
的整行从发布版本中消失。