bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

utimensat: Fix test failures on macOS


From: Bruno Haible
Subject: utimensat: Fix test failures on macOS
Date: Sat, 02 Jan 2021 19:35:59 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-197-generic; KDE/5.18.0; x86_64; ; )

On macOS 10.13, I'm seeing test failures:

FAIL: test-fdutimensat
======================

./test-utimens.h:75: assertion 'func (BASE "file", ts) == -1' failed
FAIL test-fdutimensat (exit status: 134)

FAIL: test-utimensat
====================

./test-utimens.h:75: assertion 'func (BASE "file", ts) == -1' failed
FAIL test-utimensat (exit status: 134)

Once I add the validation of the tv_nsec values to the Gnulib code, another
failure remains:

FAIL: test-fdutimensat
======================

./test-utimens.h:164: assertion 'func (BASE "link/", NULL) == -1' failed
FAIL test-fdutimensat (exit status: 134)

FAIL: test-utimensat
====================

./test-utimens.h:164: assertion 'func (BASE "link/", NULL) == -1' failed
FAIL test-utimensat (exit status: 134)

A missing recognition of a trailing slash, like in the previous patch.


This patch fixes both issues:


2021-01-02  Bruno Haible  <bruno@clisp.org>

        utimensat: Fix test failures on macOS 10.13.
        * lib/utimensat.c: Include <string.h>, <sys/stat.h>.
        (rpl_utimensat): Check against invalid tv_nsec values. Before calling
        utimensat, recognize a filename ending in a slash that does not point
        to a directory.

diff --git a/lib/utimensat.c b/lib/utimensat.c
index 2cea64f..1daff88 100644
--- a/lib/utimensat.c
+++ b/lib/utimensat.c
@@ -24,6 +24,8 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
 
 #include "stat-time.h"
 #include "timespec.h"
@@ -106,6 +108,34 @@ rpl_utimensat (int fd, char const *file, struct timespec 
const times[2],
         }
 #  endif
 # endif
+# if defined __APPLE__ && defined __MACH__
+      /* macOS 10.13 does not reject invalid tv_nsec values either.  */
+      if (times
+          && ((times[0].tv_nsec != UTIME_OMIT
+               && times[0].tv_nsec != UTIME_NOW
+               && ! (0 <= times[0].tv_nsec
+                     && times[0].tv_nsec < TIMESPEC_HZ))
+              || (times[1].tv_nsec != UTIME_OMIT
+                  && times[1].tv_nsec != UTIME_NOW
+                  && ! (0 <= times[1].tv_nsec
+                        && times[1].tv_nsec < TIMESPEC_HZ))))
+        {
+          errno = EINVAL;
+          return -1;
+        }
+      size_t len = strlen (file);
+      if (len > 0 && file[len - 1] == '/')
+        {
+          struct stat statbuf;
+          if (fstatat (fd, file, &statbuf, 0) < 0)
+            return -1;
+          if (!S_ISDIR (statbuf.st_mode))
+            {
+              errno = ENOTDIR;
+              return -1;
+            }
+        }
+# endif
       result = utimensat (fd, file, times, flag);
       /* Linux kernel 2.6.25 has a bug where it returns EINVAL for
          UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which




reply via email to

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