]> Savannah Git Hosting - gnulib.git/commitdiff
futimens: don’t assume struct timespec layout
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 15 Aug 2017 23:47:22 +0000 (16:47 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 15 Aug 2017 23:48:38 +0000 (16:48 -0700)
* m4/futimens.m4 (gl_FUNC_FUTIMENS):
* m4/utimensat.m4 (gl_FUNC_UTIMENSAT):
* tests/test-fdutimensat.c (main):
* tests/test-futimens.h (test_futimens):
* tests/test-lutimens.h (test_lutimens):
* tests/test-utimens.h (test_utimens):
* tests/test-utimensat.c (main):
Don’t assume that struct timespec is a two-member structure in
tv_sec, tv_nsec order.  Although this is true on all platforms we
know about, POSIX does not guarantee it.

ChangeLog
m4/futimens.m4
m4/utimensat.m4
tests/test-fdutimensat.c
tests/test-futimens.h
tests/test-lutimens.h
tests/test-utimens.h
tests/test-utimensat.c

index 3d87c9013fe8eece07141ea14330ec0c6a343331..bc0c169911a65983190aa4642c7ea1fa6bee9d4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2017-08-15  Paul Eggert  <eggert@cs.ucla.edu>
 
+       futimens: don’t assume struct timespec layout
+       * m4/futimens.m4 (gl_FUNC_FUTIMENS):
+       * m4/utimensat.m4 (gl_FUNC_UTIMENSAT):
+       * tests/test-fdutimensat.c (main):
+       * tests/test-futimens.h (test_futimens):
+       * tests/test-lutimens.h (test_lutimens):
+       * tests/test-utimens.h (test_utimens):
+       * tests/test-utimensat.c (main):
+       Don’t assume that struct timespec is a two-member structure in
+       tv_sec, tv_nsec order.  Although this is true on all platforms we
+       know about, POSIX does not guarantee it.
+
        rename: document+test NetBSD rename
        Test failure reported by Bruno Haible in:
        http://lists.gnu.org/archive/html/bug-gnulib/2017-08/msg00104.html
index 12bed9822d06f6e78c8f7588a26da1b27ad112d4..d68bff3a7d798a5a06de35831a9b22b2804a0047 100644 (file)
@@ -23,10 +23,14 @@ AC_DEFUN([gl_FUNC_FUTIMENS],
 #include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
-]], [[struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_NOW } };
+]], [[struct timespec ts[2];
       int fd = creat ("conftest.file", 0600);
       struct stat st;
       if (fd < 0) return 1;
+      ts[0].tv_sec = 1;
+      ts[0].tv_nsec = UTIME_OMIT;
+      ts[1].tv_sec = 1;
+      ts[1].tv_nsec = UTIME_NOW;
       errno = 0;
       if (futimens (AT_FDCWD, NULL) == 0) return 2;
       if (errno != EBADF) return 3;
index b4666c096ac7c6ccdd04c58088c56bdb6dbe6c62..78da3cc9443e0d1d78797ae4f0495a72b3002c5a 100644 (file)
@@ -34,14 +34,22 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
               }
               /* Test whether UTIME_NOW and UTIME_OMIT work.  */
               {
-                struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_NOW } };
+                struct timespec ts[2];
+                ts[0].tv_sec = 1;
+                ts[0].tv_nsec = UTIME_OMIT;
+                ts[1].tv_sec = 1;
+                ts[1].tv_nsec = UTIME_NOW;
                 if (utimensat (AT_FDCWD, f, ts, 0))
                   result |= 4;
               }
               sleep (1);
               {
-                struct timespec ts[2] = { { 1, UTIME_NOW }, { 1, UTIME_OMIT } };
                 struct stat st;
+                struct timespec ts[2];
+                ts[0].tv_sec = 1;
+                ts[0].tv_nsec = UTIME_NOW;
+                ts[1].tv_sec = 1;
+                ts[1].tv_nsec = UTIME_OMIT;
                 if (utimensat (AT_FDCWD, f, ts, 0))
                   result |= 8;
                 if (stat (f, &st))
index fa35bc4cf3ed118816900dacb3c40dea7b519b3d..b42cba3f2b6eeb7916c85b71787c280bbca1858f 100644 (file)
@@ -125,8 +125,11 @@ main (void)
   ASSERT (fdutimensat (AT_FDCWD, fd, ".", NULL, 0) == -1);
   ASSERT (errno == ENOTDIR);
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
     struct stat st;
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     ASSERT (fdutimensat (fd, dfd, BASE "dir/file", ts, 0) == 0);
     ASSERT (stat ("file", &st) == 0);
     ASSERT (st.st_atime == Y2K);
index 40bcb9ee6b2bc7ff50a0b6228d40da910ebe67ee..727be3bd8da65b7a50f5843336d5f4f619e7275a 100644 (file)
@@ -97,13 +97,21 @@ test_futimens (int (*func) (int, struct timespec const *),
     ASSERT (errno == EBADF);
   }
   {
-    struct timespec ts[2] = { { Y2K, UTIME_BOGUS_POS }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = UTIME_BOGUS_POS;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = 0;
     errno = 0;
     ASSERT (func (fd, ts) == -1);
     ASSERT (errno == EINVAL);
   }
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, UTIME_BOGUS_NEG } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = UTIME_BOGUS_NEG;
     errno = 0;
     ASSERT (func (fd, ts) == -1);
     ASSERT (errno == EINVAL);
@@ -115,7 +123,11 @@ test_futimens (int (*func) (int, struct timespec const *),
 
   /* Set both times.  */
   {
-    struct timespec ts[2] = { { Y2K, BILLION / 2 - 1 }, { Y2K, BILLION - 1 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = BILLION / 2 - 1;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = BILLION - 1;
     ASSERT (func (fd, ts) == 0);
     ASSERT (fstat (fd, &st2) == 0);
     ASSERT (st2.st_atime == Y2K);
@@ -131,7 +143,11 @@ test_futimens (int (*func) (int, struct timespec const *),
   /* Play with UTIME_OMIT, UTIME_NOW.  */
   {
     struct stat st3;
-    struct timespec ts[2] = { { BILLION, UTIME_OMIT }, { 0, UTIME_NOW } };
+    struct timespec ts[2];
+    ts[0].tv_sec = BILLION;
+    ts[0].tv_nsec = UTIME_OMIT;
+    ts[1].tv_sec = 0;
+    ts[1].tv_nsec = UTIME_NOW;
     nap ();
     ASSERT (func (fd, ts) == 0);
     ASSERT (fstat (fd, &st3) == 0);
index b590855f5a85b8ce083587b53eeb19e032a6b485..e18f2495f881502ec2bfd9804861f0658b2e3120 100644 (file)
@@ -44,7 +44,10 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
   ASSERT (st1.st_atime != Y2K);
   ASSERT (st1.st_mtime != Y2K);
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     errno = 0;
     ASSERT (func (BASE "file/", ts) == -1);
     ASSERT (errno == ENOTDIR);
@@ -53,7 +56,10 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
     ASSERT (st1.st_mtime == st2.st_mtime);
   }
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     nap ();
     ASSERT (func (BASE "file", ts) == 0);
   }
@@ -106,13 +112,21 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
 
   /* Invalid arguments.  */
   {
-    struct timespec ts[2] = { { Y2K, UTIME_BOGUS_POS }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = UTIME_BOGUS_POS;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = 0;
     errno = 0;
     ASSERT (func (BASE "link", ts) == -1);
     ASSERT (errno == EINVAL);
   }
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, UTIME_BOGUS_NEG } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = UTIME_BOGUS_NEG;
     errno = 0;
     ASSERT (func (BASE "link", ts) == -1);
     ASSERT (errno == EINVAL);
@@ -127,7 +141,11 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
 
   /* Set both times.  */
   {
-    struct timespec ts[2] = { { Y2K, BILLION / 2 - 1 }, { Y2K, BILLION - 1 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = BILLION / 2 - 1;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = BILLION - 1;
     nap ();
     ASSERT (func (BASE "link", ts) == 0);
     ASSERT (lstat (BASE "link", &st2) == 0);
@@ -147,7 +165,11 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
   /* Play with UTIME_OMIT, UTIME_NOW.  */
   {
     struct stat st3;
-    struct timespec ts[2] = { { BILLION, UTIME_OMIT }, { 0, UTIME_NOW } };
+    struct timespec ts[2];
+    ts[0].tv_sec = BILLION;
+    ts[0].tv_nsec = UTIME_OMIT;
+    ts[1].tv_sec = 0;
+    ts[1].tv_nsec = UTIME_NOW;
     nap ();
     ASSERT (func (BASE "link", ts) == 0);
     ASSERT (lstat (BASE "link", &st3) == 0);
@@ -181,7 +203,10 @@ test_lutimens (int (*func) (char const *, struct timespec const *), bool print)
   ASSERT (symlink (BASE "dir", BASE "link") == 0);
   ASSERT (mkdir (BASE "dir", 0700) == 0);
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     ASSERT (func (BASE "link/", ts) == 0);
   }
   /* On cygwin 1.5, stat() changes atime of directories, so only check
index 8af2efe8f348c1cd08e0ae95980cf47bd6fb4147..ff538750617851441f22f48cd9a54535d0a94c4f 100644 (file)
@@ -66,19 +66,30 @@ test_utimens (int (*func) (char const *, struct timespec const *), bool print)
   ASSERT (func ("", NULL) == -1);
   ASSERT (errno == ENOENT);
   {
-    struct timespec ts[2] = { { Y2K, UTIME_BOGUS_POS }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = UTIME_BOGUS_POS;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = 0;
     errno = 0;
     ASSERT (func (BASE "file", ts) == -1);
     ASSERT (errno == EINVAL);
   }
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, UTIME_BOGUS_NEG } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = UTIME_BOGUS_NEG;
     errno = 0;
     ASSERT (func (BASE "file", ts) == -1);
     ASSERT (errno == EINVAL);
   }
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     errno = 0;
     ASSERT (func (BASE "file/", ts) == -1);
     ASSERT (errno == ENOTDIR || errno == EINVAL);
@@ -90,7 +101,11 @@ test_utimens (int (*func) (char const *, struct timespec const *), bool print)
 
   /* Set both times.  */
   {
-    struct timespec ts[2] = { { Y2K, BILLION / 2 - 1 }, { Y2K, BILLION - 1 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = BILLION / 2 - 1;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = BILLION - 1;
     ASSERT (func (BASE "file", ts) == 0);
     ASSERT (stat (BASE "file", &st2) == 0);
     ASSERT (st2.st_atime == Y2K);
@@ -106,7 +121,11 @@ test_utimens (int (*func) (char const *, struct timespec const *), bool print)
   /* Play with UTIME_OMIT, UTIME_NOW.  */
   {
     struct stat st3;
-    struct timespec ts[2] = { { BILLION, UTIME_OMIT }, { 0, UTIME_NOW } };
+    struct timespec ts[2];
+    ts[0].tv_sec = BILLION;
+    ts[0].tv_nsec = UTIME_OMIT;
+    ts[1].tv_sec = 0;
+    ts[1].tv_nsec = UTIME_NOW;
     nap ();
     ASSERT (func (BASE "file", ts) == 0);
     ASSERT (stat (BASE "file", &st3) == 0);
@@ -145,7 +164,10 @@ test_utimens (int (*func) (char const *, struct timespec const *), bool print)
   ASSERT (func (BASE "link/", NULL) == -1);
   ASSERT (errno == ENOTDIR);
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1] = ts[0];
     ASSERT (func (BASE "link", ts) == 0);
     ASSERT (lstat (BASE "link", &st2) == 0);
     /* Can't compare atimes, since lstat() changes symlink atime on cygwin.  */
index de5ae5afe48617edb634bf56f35668e106120234..e5a3685f5ce537247197e1eb72520d0bf5b35fdc 100644 (file)
@@ -101,8 +101,12 @@ main (void)
   ASSERT (utimensat (fd, ".", NULL, 0) == -1);
   ASSERT (errno == ENOTDIR);
   {
-    struct timespec ts[2] = { { Y2K, 0 }, { Y2K, 0 } };
+    struct timespec ts[2];
     struct stat st;
+    ts[0].tv_sec = Y2K;
+    ts[0].tv_nsec = 0;
+    ts[1].tv_sec = Y2K;
+    ts[1].tv_nsec = 0;
     ASSERT (utimensat (dfd, BASE "dir/file", ts, AT_SYMLINK_NOFOLLOW) == 0);
     ASSERT (stat ("file", &st) == 0);
     ASSERT (st.st_atime == Y2K);