Changeset 736983f1 in rtems


Ignore:
Timestamp:
Sep 13, 2013, 1:26:48 PM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
d1c5c01f
Parents:
c5b2d79
git-author:
Sebastian Huber <sebastian.huber@…> (09/13/13 13:26:48)
git-committer:
Sebastian Huber <sebastian.huber@…> (09/13/13 14:47:55)
Message:

fstests/fstime: Fix according to POSIX

ftruncate() and open() with O_TRUNC shall upon successful completion
mark for update the st_ctime and st_mtime fields of the file.

truncate() shall upon successful completion, if the file size is
changed, mark for update the st_ctime and st_mtime fields of the file.

The POSIX standard "The Open Group Base Specifications Issue 7", IEEE
Std 1003.1, 2013 Edition says nothing about the behaviour of truncate()
if the file size remains unchanged.

Future directions of the standard may mandate the behaviour specified in
ftruncate():

http://austingroupbugs.net/view.php?id=489

File:
1 edited

Legend:

Unmodified
Added
Removed
  • testsuites/fstests/fstime/test.c

    rc5b2d79 r736983f1  
    2323#include <utime.h>
    2424
     25#ifdef __rtems__
    2526#include "fstest.h"
    2627#include "pmacros.h"
     28#else
     29#include <assert.h>
     30#define rtems_test_assert(x) assert(x)
     31#define TIME_PRECISION  (2)
     32#define TIME_EQUAL(x,y) (abs((x)-(y))<TIME_PRECISION)
     33#endif
     34
     35static int do_create(const char *path, int oflag, mode_t mode)
     36{
     37  int fd = open (path, O_CREAT | oflag, mode);
     38  rtems_test_assert (fd >= 0);
     39
     40  return fd;
     41}
     42
     43static int do_open(const char *path, int oflag)
     44{
     45  int fd = open (path, O_CREAT | oflag);
     46  rtems_test_assert (fd >= 0);
     47
     48  return fd;
     49}
    2750
    2851static void time_test01 (void)
    2952{
    30   struct stat statbuf;
     53  struct stat st;
    3154  struct utimbuf timbuf;
    32   int status = 0;
     55  int status;
    3356  int fd;
    34   time_t ctime1, mtime1;
    35   time_t ctime2, mtime2;
    36   char *readbuf;
    37   char *databuf = "TEST";
    38   char *file01 = "test01";
    39   char *file02 = "test02";
    40   char *file03 = "test03";
    41   char *dir01 = "dir01";
     57  time_t creation_time;
     58  time_t truncation_time;
     59  time_t dir01_creation_time;
     60  char databuf[] = "TEST";
     61  char readbuf[sizeof(databuf)];
     62  const char *file01 = "test01";
     63  const char *file02 = "test02";
     64  const char *file03 = "test03";
     65  const char *dir01 = "dir01";
    4266
    4367  int n;
     
    5579
    5680  /*
     81   * Sleep a few seconds
     82   */
     83  puts ("Sleep a few seconds");
     84  sleep (3 * TIME_PRECISION);
     85
     86  /*
    5787   * Create the test files
    5888   */
    59   fd = open (file01, O_CREAT | O_WRONLY, mode);
     89  fd = do_create (file01, O_WRONLY, mode);
    6090  n = write (fd, databuf, len);
    6191  rtems_test_assert (n == len);
     
    6393  rtems_test_assert (status == 0);
    6494
    65   fd = open (file02, O_CREAT | O_WRONLY, mode);
     95  fd = do_create (file02, O_WRONLY, mode);
    6696  n = write (fd, databuf, len);
    6797  rtems_test_assert (n == len);
     
    70100
    71101  /* A simple C version of touch */
    72   fd = open (file03, O_CREAT | O_WRONLY, mode);
     102  fd = do_create (file03, O_WRONLY, mode);
    73103  status = close (fd);
    74104  rtems_test_assert (status == 0);
     
    80110   * st_mtime fields of the parent directory.
    81111   */
    82   status = stat (file01, &statbuf);
    83   rtems_test_assert (status == 0);
    84   ctime1 = statbuf.st_ctime;
    85   mtime1 = statbuf.st_mtime;
    86 
    87   status = stat (".", &statbuf);
    88   rtems_test_assert (status == 0);
    89   ctime2 = statbuf.st_ctime;
    90   mtime2 = statbuf.st_mtime;
     112  status = stat (file01, &st);
     113  rtems_test_assert (status == 0);
    91114
    92115  /*
    93116   * Make sure they are the same
    94117   */
    95 
    96   rtems_test_assert (TIME_EQUAL (ctime1, mtime1));
    97   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
    98   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
    99 
    100 
    101   status = stat (file02, &statbuf);
    102   rtems_test_assert (status == 0);
    103   ctime1 = statbuf.st_ctime;
    104   mtime1 = statbuf.st_mtime;
    105 
    106   status = stat (".", &statbuf);
    107   rtems_test_assert (status == 0);
    108   ctime2 = statbuf.st_ctime;
    109   mtime2 = statbuf.st_mtime;
     118  rtems_test_assert (st.st_ctime == st.st_mtime);
     119
     120  creation_time = st.st_ctime;
     121
     122  status = stat (".", &st);
     123  rtems_test_assert (status == 0);
    110124
    111125  /*
    112126   * Make sure they are the same
    113127   */
    114   rtems_test_assert (TIME_EQUAL (ctime1, mtime1));
    115   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
    116   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
     128  rtems_test_assert (st.st_ctime == st.st_mtime);
     129  rtems_test_assert (TIME_EQUAL (creation_time, st.st_mtime));
     130  rtems_test_assert (TIME_EQUAL (creation_time, st.st_ctime));
     131
     132  status = stat (file02, &st);
     133  rtems_test_assert (status == 0);
     134
     135  /*
     136   * Make sure they are the same
     137   */
     138  rtems_test_assert (st.st_ctime == st.st_mtime);
     139  rtems_test_assert (TIME_EQUAL (creation_time, st.st_mtime));
     140  rtems_test_assert (TIME_EQUAL (creation_time, st.st_ctime));
     141
     142  status = stat (file03, &st);
     143  rtems_test_assert (status == 0);
     144
     145  /*
     146   * Make sure they are the same
     147   */
     148  rtems_test_assert (st.st_ctime == st.st_mtime);
     149  rtems_test_assert (TIME_EQUAL (creation_time, st.st_mtime));
     150  rtems_test_assert (TIME_EQUAL (creation_time, st.st_ctime));
    117151
    118152  /*
     
    120154   */
    121155  puts ("Sleep a few seconds");
    122 
    123   sleep (TIME_PRECISION);
     156  sleep (3 * TIME_PRECISION);
    124157
    125158  /*
     
    144177   * Truncate an empty file which does not change the length.
    145178   */
    146   fd = open (file03, O_TRUNC | O_WRONLY, mode);
    147   status = close (fd);
    148   rtems_test_assert (status == 0);
    149 
    150   /*
     179  fd = do_open (file03, O_TRUNC | O_WRONLY);
     180  status = close (fd);
     181  rtems_test_assert (status == 0);
     182
     183  /*
     184   * ftruncate() and open() with O_TRUNC shall upon successful completion mark
     185   * for update the st_ctime and st_mtime fields of the file.
    151186   *
    152    *  truncate shall not modify the file offset for any open file
    153    *   descriptions associated with the file. Upon successful completion,
    154    *   if the file size is changed, this function shall mark for update
    155    *   the st_ctime and st_mtime fields of the file
     187   * truncate() shall upon successful completion, if the file size is changed,
     188   * mark for update the st_ctime and st_mtime fields of the file.
    156189   *
    157    *  open with O_TRUNC must update the file fields.
    158    */
    159 
    160   /*
    161    * file01 shall not update
    162    */
    163   status = stat (file01, &statbuf);
    164   rtems_test_assert (status == 0);
    165   ctime2 = statbuf.st_ctime;
    166   mtime2 = statbuf.st_mtime;
    167 
    168   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
    169   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
     190   * The POSIX standard "The Open Group Base Specifications Issue 7", IEEE Std
     191   * 1003.1, 2013 Edition says nothing about the behaviour of truncate() if the
     192   * file size remains unchanged.
     193   *
     194   * Future directions of the standard may mandate the behaviour specified in
     195   * ftruncate():
     196   *
     197   * http://austingroupbugs.net/view.php?id=489
     198   */
     199
     200  /*
     201   * file01 is currently unspecified
     202   */
     203  status = stat (file01, &st);
     204  rtems_test_assert (status == 0);
     205
     206  rtems_test_assert (st.st_ctime == st.st_mtime);
     207  if (TIME_EQUAL (creation_time, st.st_ctime)) {
     208    puts ("WARNING: truncate() behaviour may violate future POSIX standard");
     209  }
     210
     211  truncation_time = st.st_ctime;
    170212
    171213  /*
    172214   * file02 shall update
    173215   */
    174   status = stat (file02, &statbuf);
    175   rtems_test_assert (status == 0);
    176   ctime2 = statbuf.st_ctime;
    177   mtime2 = statbuf.st_mtime;
    178 
    179   rtems_test_assert (TIME_EQUAL (ctime2, mtime2));
    180   rtems_test_assert (!TIME_EQUAL (ctime1, mtime2));
    181   rtems_test_assert (!TIME_EQUAL (ctime1, ctime2));
     216  status = stat (file02, &st);
     217  rtems_test_assert (status == 0);
     218
     219  rtems_test_assert (st.st_ctime == st.st_mtime);
     220  rtems_test_assert (!TIME_EQUAL (creation_time, st.st_ctime));
    182221
    183222  /*
    184223   * file03 shall update
    185224   */
    186   status = stat (file03, &statbuf);
    187   rtems_test_assert (status == 0);
    188   ctime2 = statbuf.st_ctime;
    189   mtime2 = statbuf.st_mtime;
    190 
    191   rtems_test_assert (TIME_EQUAL (ctime2, mtime2));
    192   rtems_test_assert (!TIME_EQUAL (ctime1, mtime2));
    193   rtems_test_assert (!TIME_EQUAL (ctime1, ctime2));
     225  status = stat (file03, &st);
     226  rtems_test_assert (status == 0);
     227
     228  rtems_test_assert (st.st_ctime == st.st_mtime);
     229  rtems_test_assert (!TIME_EQUAL (creation_time, st.st_ctime));
    194230
    195231  /*
    196232   *  Upon successful completion, mkdir() shall mark for update the
    197    *  5st_atime, st_ctime, and st_mtime fields of the directory.
     233   *  st_atime, st_ctime, and st_mtime fields of the directory.
    198234   *  Also, the st_ctime and st_mtime fields of the directory that
    199235   *  contains the new entry shall be marked for update.
    200236   */
    201   status = stat (dir01, &statbuf);
    202   rtems_test_assert (status == 0);
    203   ctime2 = statbuf.st_ctime;
    204   mtime2 = statbuf.st_mtime;
    205   rtems_test_assert (TIME_EQUAL (ctime2, mtime2));
    206   rtems_test_assert (!TIME_EQUAL (ctime1, mtime2));
    207   rtems_test_assert (!TIME_EQUAL (ctime1, ctime2));
    208 
    209   status = stat (".", &statbuf);
    210   rtems_test_assert (status == 0);
    211   ctime2 = statbuf.st_ctime;
    212   mtime2 = statbuf.st_mtime;
    213 
    214   rtems_test_assert (!TIME_EQUAL (ctime1, ctime2));
    215   rtems_test_assert (!TIME_EQUAL (ctime1, mtime2));
     237  status = stat (dir01, &st);
     238  rtems_test_assert (status == 0);
     239
     240  rtems_test_assert (st.st_ctime == st.st_mtime);
     241
     242  dir01_creation_time = st.st_ctime;
     243
     244  status = stat (".", &st);
     245  rtems_test_assert (status == 0);
     246
     247  rtems_test_assert (st.st_ctime == st.st_mtime);
     248  rtems_test_assert (TIME_EQUAL (dir01_creation_time, st.st_mtime));
     249
     250  /*
     251   * Sleep a few seconds
     252   */
     253  puts ("Sleep a few seconds");
     254  sleep (3 * TIME_PRECISION);
    216255
    217256  /*
     
    223262   * read file01, and this should not uptate st_mtime and st_ctime
    224263   */
    225   readbuf = (char *) malloc (len + 1);
    226   fd = open (file01, O_RDONLY);
    227   rtems_test_assert (fd != -1);
     264  fd = do_open (file01, O_RDONLY);
    228265  n = read (fd, readbuf, len);
    229266  rtems_test_assert (n == len);
    230   status = fstat (fd, &statbuf);
    231 
    232   ctime2 = statbuf.st_ctime;
    233   mtime2 = statbuf.st_mtime;
    234 
    235   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
    236   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
     267  status = fstat (fd, &st);
     268  rtems_test_assert (status == 0);
     269
     270  rtems_test_assert (st.st_ctime == st.st_mtime);
     271  rtems_test_assert (TIME_EQUAL (truncation_time, st.st_mtime));
    237272
    238273  status = close (fd);
     
    241276   * write file01, and this should uptate st_mtime st_ctime
    242277   */
    243   readbuf = (char *) malloc (len + 1);
    244   fd = open (file01, O_WRONLY);
    245   rtems_test_assert (fd != -1);
     278  fd = do_open (file01, O_WRONLY);
    246279  n = write (fd, databuf, len);
    247280  rtems_test_assert (n == len);
    248   status = fstat (fd, &statbuf);
    249 
    250   ctime2 = statbuf.st_ctime;
    251   mtime2 = statbuf.st_mtime;
    252 
    253   rtems_test_assert (!TIME_EQUAL (ctime1, ctime2));
    254   rtems_test_assert (!TIME_EQUAL (ctime1, mtime2));
     281  status = fstat (fd, &st);
     282
     283  rtems_test_assert (st.st_ctime == st.st_mtime);
     284  rtems_test_assert (!TIME_EQUAL (truncation_time, st.st_mtime));
    255285  status = close (fd);
    256286  rtems_test_assert (status == 0);
     
    260290   *  of the file named by the path argument.
    261291   */
    262   timbuf.actime = ctime1;
    263   timbuf.modtime = mtime1;
     292  timbuf.actime = creation_time;
     293  timbuf.modtime = creation_time;
    264294
    265295  status = utime (file01, &timbuf);
    266296  rtems_test_assert (status == 0);
    267297
    268   status = stat (file01, &statbuf);
    269   ctime2 = statbuf.st_atime;
    270   mtime2 = statbuf.st_mtime;
    271 
    272   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
    273   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
     298  status = stat (file01, &st);
     299  rtems_test_assert (status == 0);
     300
     301  rtems_test_assert (st.st_atime == st.st_mtime);
     302  rtems_test_assert (TIME_EQUAL (creation_time, st.st_atime));
     303  rtems_test_assert (!TIME_EQUAL (creation_time, st.st_ctime));
    274304
    275305  status = utime (dir01, &timbuf);
    276306  rtems_test_assert (status == 0);
    277307
    278   status = stat (dir01, &statbuf);
    279   ctime2 = statbuf.st_atime;
    280   mtime2 = statbuf.st_mtime;
    281 
    282   rtems_test_assert (TIME_EQUAL (ctime1, ctime2));
    283   rtems_test_assert (TIME_EQUAL (ctime1, mtime2));
    284 
     308  status = stat (dir01, &st);
     309  rtems_test_assert (status == 0);
     310
     311  rtems_test_assert (st.st_atime == st.st_mtime);
     312  rtems_test_assert (TIME_EQUAL (creation_time, st.st_atime));
     313  rtems_test_assert (!TIME_EQUAL (creation_time, st.st_ctime));
    285314}
    286315
     
    289318 * if they are changed. Thest tests don't check atime
    290319 */
     320#ifdef __rtems__
    291321void test (void)
     322#else
     323int main(int argc, char **argv)
     324#endif
    292325{
    293326
     
    295328  time_test01();
    296329  puts( "*** END OF TIME TEST ***" );
     330
     331#ifndef __rtems__
     332  return 0;
     333#endif
    297334}
Note: See TracChangeset for help on using the changeset viewer.