bug-gnulib
[Top][All Lists]
Advanced

[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);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]