Hi Jim, The stat-time test fails for three reasons on mingw:
1) It uses the function sleep(), which does not exist. Fix: Simply use the 'sleep' module. 2) When run for the second time, opening the test files (t-stt-stamp1 etc.) fails, because these files were not cleaned up by the previous run. Reason: unlink() on a read-only file fails with EPERM. This is documented here: http://msdn2.microsoft.com/en-us/library/aa363915(VS.85).aspx ("To delete a read-only file, first you must remove the read-only attribute."). Fix: chmod the files before remving them. 3) The comparisons between st_mtime and st_ctime fail. The reason is that 1. st_ctime means "creation time" on Windows, not "change time", 2. in practice st_time is st_mtime plus/minus a fixed offset. This offset was 48 sec one machine I tested on, and 75 minutes on another machine. Furtheremore there appear to be differences between empty and nonempty files. (gdb) print statinfo[0] /* stamp1 */ $1 = {st_atime = 1208801842, st_mtime = 1208801842, st_ctime = 1208801794} (gdb) print statinfo[1] /* testfile */ $2 = {st_atime = 1208801844, st_mtime = 1208801844, st_ctime = 1208801796} (gdb) print statinfo[2] /* stamp2 */ $3 = {st_atime = 1208801846, st_mtime = 1208801846, st_ctime = 1208801798} I created 8 files, then wrote, renamed, chmoded some of them selectively. Creation time: 14:49:29 Write time: 14:50:30 Rename time: 14:51:15 chmod time: 14:52:30 Result: Modified Created ls -l ls -lc mtime ctime file1 created 14:49 13:34 file2 created renamed 14:49 13:36 file3 created chmoded 14:49 13:37 file4 created renamed chmoded 14:49 13:37 file5 created written 13:35 13:35 file6 created written renamed 13:35 13:35 file7 created written chmoded 13:35 13:35 file8 created written renamed chmoded 13:35 13:35 When the files are created with "echo > file" rather than "touch file", the results are different: Creation time: 15:05:20 Write time: 15:06:22 Rename time: 15:07:26 chmod time: 15:08:36 Result: Modified Created ls -l ls -lc mtime ctime file1 created+written 13:50 13:50 file2 created+written renamed 13:50 13:50 file3 created+written chmoded 13:50 13:50 file4 created+written renamed chmoded 13:50 13:50 file5 created+written written 13:51 13:51 file6 created+written written renamed 13:51 13:51 file7 created+written written chmoded 13:51 13:51 file8 created+written written renamed chmoded 13:51 13:51 I don't see how to fix this (other than by overriding stat(), lstat() etc.) This is the total set of fixes. OK to apply? 2008-04-27 Bruno Haible <[EMAIL PROTECTED]> * modules/stat-time-tests (Depends-on): Add sleep. * tests/test-stat-time.c (force_unlink): New function. (cleanup): Use it. (test_mtime): Remove the ctime related tests. (test_ctime): New function, containing the ctime related tests. (main): Call test_ctime, except on native Windows platforms. *** modules/stat-time-tests.orig 2008-04-27 20:58:25.000000000 +0200 --- modules/stat-time-tests 2008-04-27 20:41:58.000000000 +0200 *************** *** 3,8 **** --- 3,9 ---- Depends-on: time + sleep configure.ac: *** tests/test-stat-time.c.orig 2008-04-27 20:58:25.000000000 +0200 --- tests/test-stat-time.c 2008-04-27 20:58:21.000000000 +0200 *************** *** 42,55 **** enum { NFILES = 4 }; static void cleanup (int sig) { /* Remove temporary files. */ ! unlink ("t-stt-stamp1"); ! unlink ("t-stt-testfile"); ! unlink ("t-stt-stamp2"); ! unlink ("t-stt-renamed"); ! unlink ("t-stt-stamp3"); if (sig != 0) _exit (1); --- 42,64 ---- enum { NFILES = 4 }; static void + force_unlink (const char *filename) + { + /* This chmod is necessary on mingw, where unlink() of a read-only file + fails with EPERM. */ + chmod (filename, 0600); + unlink (filename); + } + + static void cleanup (int sig) { /* Remove temporary files. */ ! force_unlink ("t-stt-stamp1"); ! force_unlink ("t-stt-testfile"); ! force_unlink ("t-stt-stamp2"); ! force_unlink ("t-stt-renamed"); ! force_unlink ("t-stt-stamp3"); if (sig != 0) _exit (1); *************** *** 117,123 **** /* Use the struct stat fields directly. */ ASSERT (statinfo[0].st_mtime < statinfo[2].st_mtime); /* mtime(stamp1) < mtime(stamp2) */ ASSERT (statinfo[2].st_mtime < statinfo[3].st_mtime); /* mtime(stamp2) < mtime(stamp3) */ - ASSERT (statinfo[2].st_mtime < statinfo[1].st_ctime); /* mtime(stamp2) < ctime(renamed) */ /* Now check the result of the access functions. */ ASSERT (modtimes[0].tv_sec < modtimes[2].tv_sec); /* mtime(stamp1) < mtime(stamp2) */ --- 126,131 ---- *************** *** 130,135 **** --- 138,149 ---- ts = get_stat_mtime (&statinfo[i]); ASSERT (ts.tv_sec == statinfo[i].st_mtime); } + } + + static void + test_ctime (const struct stat *statinfo) + { + ASSERT (statinfo[2].st_mtime < statinfo[1].st_ctime); /* mtime(stamp2) < ctime(renamed) */ ASSERT (statinfo[2].st_mtime < statinfo[1].st_ctime); /* mtime(stamp2) < ctime(renamed) */ } *************** *** 176,181 **** --- 190,201 ---- cleanup (0); prepare_test (statinfo, modtimes); test_mtime (statinfo, modtimes); + /* Skip the ctime tests on native Windows platforms, because there st_ctime + is either the same as st_mtime (plus or minus an offset) or set to the + file _creation_ time, and is not influenced by rename or chmod. */ + #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) + test_ctime (statinfo); + #endif test_birthtime (statinfo, modtimes, birthtimes); cleanup (0);
