[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
stat-time test on mingw
From: |
Bruno Haible |
Subject: |
stat-time test on mingw |
Date: |
Sun, 27 Apr 2008 21:08:50 +0200 |
User-agent: |
KMail/1.5.4 |
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 <address@hidden>
* 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);
- stat-time test on mingw,
Bruno Haible <=