Skip to content

Commit 3f7e055

Browse files
committed
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.
1 parent bedd8d1 commit 3f7e055

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

src/fs_base_utime_generic.hpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
#include <sys/stat.h>
2626
#include <sys/time.h>
2727

28-
#if __APPLE__
29-
#import <sys/param.h> /* MAXPATHLEN */
30-
#endif
28+
#include "futimesat.hpp" /* futimesat replacement */
3129

3230
#ifndef UTIME_NOW
3331
# define UTIME_NOW ((1l << 30) - 1l)
@@ -293,16 +291,7 @@ namespace fs
293291

294292
if((flags & AT_SYMLINK_NOFOLLOW) == 0) {
295293
#if __APPLE__
296-
297-
char fullpath[MAXPATHLEN];
298-
299-
if (fcntl(dirfd,F_GETPATH,fullpath) < 0)
300-
return (errno=errno,-1);
301-
302-
if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path.c_str(), MAXPATHLEN) > MAXPATHLEN)
303-
return (errno=ENAMETOOLONG,-1);
304-
305-
return ::utimes(fullpath,tvp);
294+
return _futimesat(dirfd,path.c_str(),tvp);
306295
#else
307296
return ::futimesat(dirfd,path.c_str(),tvp);
308297
#endif

src/futimesat.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "futimesat.hpp"
2+
3+
#ifdef __APPLE__
4+
#include "futimesat_osx.icpp"
5+
#endif

src/futimesat.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef __UTIMESAT_HPP__
2+
#define __UTIMESAT_HPP__
3+
4+
#if __APPLE__
5+
int
6+
_futimesat(int dirfd, const char* path, struct timeval *tvp);
7+
#endif
8+
9+
#endif

src/futimesat_osx.icpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <unistd.h>
2+
#include <string.h>
3+
#include <fcntl.h>
4+
#include <err.h>
5+
#include <sys/errno.h>
6+
#include <sys/time.h>
7+
#include <sys/param.h> /* MAXPATHLEN */
8+
9+
10+
int
11+
_futimesat(int fd, const char* path, struct timeval *tvp) {
12+
char fullpath[MAXPATHLEN];
13+
14+
// Handle absolute paths
15+
if(path[0] == '/') {
16+
return ::utimes(path,tvp);
17+
}
18+
19+
// OS X 10.12 (at least) has an issue with using AT_FDCWD in this specific call.
20+
if (fd == AT_FDCWD) {
21+
if (getcwd((char*)fullpath, MAXPATHLEN) == NULL) {
22+
return -1;
23+
}
24+
} else {
25+
if (fcntl(fd,F_GETPATH,fullpath) < 0) {
26+
return -1;
27+
}
28+
}
29+
30+
if (strlcat(fullpath, "/", MAXPATHLEN) > MAXPATHLEN || strlcat(fullpath, path, MAXPATHLEN) > MAXPATHLEN) {
31+
return (errno=ENAMETOOLONG,-1);
32+
}
33+
34+
return ::utimes(fullpath,tvp);;
35+
}

0 commit comments

Comments
 (0)