--- 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