summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-08-15 16:47:22 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-08-15 16:48:38 -0700
commit6536b952f68e49259420ee1924a238b5aa3feff3 (patch)
treed1c40d807326ea8331fc74b4172e969c019bcb54
parent9a6c7d3f6ea7c328e7760458b18fe6dfc6f8806f (diff)
downloadgnulib-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--ChangeLog12
-rw-r--r--m4/futimens.m46
-rw-r--r--m4/utimensat.m412
-rw-r--r--tests/test-fdutimensat.c5
-rw-r--r--tests/test-futimens.h24
-rw-r--r--tests/test-lutimens.h39
-rw-r--r--tests/test-utimens.h34
-rw-r--r--tests/test-utimensat.c6
8 files changed, 116 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 3d87c9013f..bc0c169911 100644
--- 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
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);