Browse Source

Fix issue with AT_FDCWD

OSX doesn’t like AT_FDCWD in it’s fcntl, but getcwd does the job.
Also fixed an issue with absolute paths in the process.
pull/384/head
Adam Knight 9 years ago
parent
commit
39b7772549
  1. 15
      src/fs_base_utime_generic.hpp
  2. 5
      src/futimesat.cpp
  3. 9
      src/futimesat.hpp
  4. 35
      src/futimesat_osx.icpp

15
src/fs_base_utime_generic.hpp

@ -25,9 +25,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#if __APPLE__
#import <sys/param.h> /* MAXPATHLEN */
#endif
#include "futimesat.hpp" /* futimesat replacement */
#ifndef UTIME_NOW #ifndef UTIME_NOW
# define UTIME_NOW ((1l << 30) - 1l) # define UTIME_NOW ((1l << 30) - 1l)
@ -293,16 +291,7 @@ namespace fs
if((flags & AT_SYMLINK_NOFOLLOW) == 0) { if((flags & AT_SYMLINK_NOFOLLOW) == 0) {
#if __APPLE__ #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 #else
return ::futimesat(dirfd,path.c_str(),tvp); return ::futimesat(dirfd,path.c_str(),tvp);
#endif #endif

5
src/futimesat.cpp

@ -0,0 +1,5 @@
#include "futimesat.hpp"
#ifdef __APPLE__
#include "futimesat_osx.icpp"
#endif

9
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

35
src/futimesat_osx.icpp

@ -0,0 +1,35 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <err.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/param.h> /* 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);;
}
Loading…
Cancel
Save