--- Modules/posixmodule.c.orig 2017-08-07 17:59:11.000000000 +1000
+++ Modules/posixmodule.c 2017-09-24 22:07:49.000000000 +1000
@@ -19,6 +19,9 @@
# pragma weak lchown
# pragma weak statvfs
# pragma weak fstatvfs
+/* utimensat and futimens not available in macOS 10.12 and earlier */
+# pragma weak utimensat
+# pragma weak futimens
#endif /* __APPLE__ */
@@ -4597,8 +4600,18 @@ static int
utime_fd(utime_t *ut, int fd)
{
#ifdef HAVE_FUTIMENS
+#ifdef __APPLE__
+ if (futimens != NULL) {
+ UTIME_TO_TIMESPEC;
+ return futimens(fd, time);
+ } else {
+ UTIME_TO_TIMEVAL;
+ return futimes(fd, time);
+ }
+#else
UTIME_TO_TIMESPEC;
return futimens(fd, time);
+#endif /* __APPLE__ */
#else
UTIME_TO_TIMEVAL;
return futimes(fd, time);
@@ -4620,8 +4633,18 @@ static int
utime_nofollow_symlinks(utime_t *ut, char *path)
{
#ifdef HAVE_UTIMENSAT
+#ifdef __APPLE__
+ if (utimensat != NULL) {
+ UTIME_TO_TIMESPEC;
+ return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
+ } else {
+ UTIME_TO_TIMEVAL;
+ return lutimes(path, time);
+ }
+#else
UTIME_TO_TIMESPEC;
return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
+#endif /* __APPLE__ */
#else
UTIME_TO_TIMEVAL;
return lutimes(path, time);
@@ -4837,7 +4860,11 @@ os_utime_impl(PyObject *module, path_t *
#endif
#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
+#ifdef __APPLE__
+ if (utimensat != NULL && ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)))
+#else
if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
+#endif
result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
else
#endif