diff --git a/src/fs_base_utime_generic.hpp b/src/fs_base_utime_generic.hpp index 13e2d8bd..bd4fd0d0 100644 --- a/src/fs_base_utime_generic.hpp +++ b/src/fs_base_utime_generic.hpp @@ -25,9 +25,7 @@ #include #include -#if __APPLE__ -#import /* MAXPATHLEN */ -#endif +#include "futimesat.hpp" /* futimesat replacement */ #ifndef UTIME_NOW # define UTIME_NOW ((1l << 30) - 1l) @@ -293,16 +291,7 @@ namespace fs if((flags & AT_SYMLINK_NOFOLLOW) == 0) { #if __APPLE__ - - char fullpath[MAXPATHLEN]; - - if (fcntl(dirfd,F_GETPATH,fullpath) < 0) - return (errno=errno,-1); - - if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path.c_str(), MAXPATHLEN) > MAXPATHLEN) - return (errno=ENAMETOOLONG,-1); - - return ::utimes(fullpath,tvp); + return _futimesat(dirfd,path.c_str(),tvp); #else return ::futimesat(dirfd,path.c_str(),tvp); #endif diff --git a/src/futimesat.cpp b/src/futimesat.cpp new file mode 100644 index 00000000..f99e606e --- /dev/null +++ b/src/futimesat.cpp @@ -0,0 +1,5 @@ +#include "futimesat.hpp" + +#ifdef __APPLE__ +#include "futimesat_osx.icpp" +#endif diff --git a/src/futimesat.hpp b/src/futimesat.hpp new file mode 100644 index 00000000..7fb3bfec --- /dev/null +++ b/src/futimesat.hpp @@ -0,0 +1,9 @@ +#ifndef __UTIMESAT_HPP__ +#define __UTIMESAT_HPP__ + +#if __APPLE__ +int +_futimesat(int dirfd, const char* path, struct timeval *tvp); +#endif + +#endif diff --git a/src/futimesat_osx.icpp b/src/futimesat_osx.icpp new file mode 100644 index 00000000..70c2986c --- /dev/null +++ b/src/futimesat_osx.icpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include /* MAXPATHLEN */ + + +int +_futimesat(int fd, const char* path, struct timeval *tvp) { + char fullpath[MAXPATHLEN]; + + // Handle absolute paths + if(path[0] == '/') { + return ::utimes(path,tvp); + } + + // OS X 10.12 (at least) has an issue with using AT_FDCWD in this specific call. + if (fd == AT_FDCWD) { + if (getcwd((char*)fullpath, MAXPATHLEN) == NULL) { + return -1; + } + } else { + if (fcntl(fd,F_GETPATH,fullpath) < 0) { + return -1; + } + } + + if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path, MAXPATHLEN) > MAXPATHLEN) { + return (errno=ENAMETOOLONG,-1); + } + + return ::utimes(fullpath,tvp);; +}