diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2017-08-15 16:47:22 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2017-08-15 16:48:38 -0700 |
commit | 6536b952f68e49259420ee1924a238b5aa3feff3 (patch) | |
tree | d1c40d807326ea8331fc74b4172e969c019bcb54 | |
parent | 9a6c7d3f6ea7c328e7760458b18fe6dfc6f8806f (diff) | |
download | gnulib-6536b952f68e49259420ee1924a238b5aa3feff3.tar.gz |
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.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | m4/futimens.m4 | 6 | ||||
-rw-r--r-- | m4/utimensat.m4 | 12 | ||||
-rw-r--r-- | tests/test-fdutimensat.c | 5 | ||||
-rw-r--r-- | tests/test-futimens.h | 24 | ||||
-rw-r--r-- | tests/test-lutimens.h | 39 | ||||
-rw-r--r-- | tests/test-utimens.h | 34 | ||||
-rw-r--r-- | tests/test-utimensat.c | 6 |
8 files changed, 116 insertions, 22 deletions
@@ -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 diff --git a/m4/futimens.m4 b/m4/futimens.m4 index 12bed9822d..d68bff3a7d 100644 --- a/m4/futimens.m4 +++ b/m4/futimens.m4 @@ -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; diff --git a/m4/utimensat.m4 b/m4/utimensat.m4 index b4666c096a..78da3cc944 100644 --- a/m4/utimensat.m4 +++ b/m4/utimensat.m4 @@ -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)) diff --git a/tests/test-fdutimensat.c b/tests/test-fdutimensat.c index fa35bc4cf3..b42cba3f2b 100644 --- a/tests/test-fdutimensat.c +++ b/tests/test-fdutimensat.c @@ -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); diff --git a/tests/test-futimens.h b/tests/test-futimens.h index 40bcb9ee6b..727be3bd8d 100644 --- a/tests/test-futimens.h +++ b/tests/test-futimens.h @@ -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); diff --git a/tests/test-lutimens.h b/tests/test-lutimens.h index b590855f5a..e18f2495f8 100644 --- a/tests/test-lutimens.h +++ b/tests/test-lutimens.h @@ -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 diff --git a/tests/test-utimens.h b/tests/test-utimens.h index 8af2efe8f3..ff53875061 100644 --- a/tests/test-utimens.h +++ b/tests/test-utimens.h @@ -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. */ diff --git a/tests/test-utimensat.c b/tests/test-utimensat.c index de5ae5afe4..e5a3685f5c 100644 --- a/tests/test-utimensat.c +++ b/tests/test-utimensat.c @@ -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); |