Discussion:
[PATCH] renameat2: port better to macOS
Paul Eggert
2017-08-16 00:10:45 UTC
Permalink
* lib/renameat2.c (renameat2): Use renameatx_np if available.
---
ChangeLog | 3 +++
lib/renameat2.c | 20 ++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bc0c16991..e4fe8dd61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2017-08-15 Paul Eggert <***@cs.ucla.edu>

+ renameat2: port better to macOS
+ * lib/renameat2.c (renameat2): Use renameatx_np if available.
+
futimens: don’t assume struct timespec layout
* m4/futimens.m4 (gl_FUNC_FUTIMENS):
* m4/utimensat.m4 (gl_FUNC_UTIMENSAT):
diff --git a/lib/renameat2.c b/lib/renameat2.c
index fd38a71e7..1e107fc50 100644
--- a/lib/renameat2.c
+++ b/lib/renameat2.c
@@ -74,12 +74,25 @@ int
renameat2 (int fd1, char const *src, int fd2, char const *dst,
unsigned int flags)
{
+ int ret_val = -1;
+ int err = EINVAL;
+
#ifdef SYS_renameat2
- int r = syscall (SYS_renameat2, fd1, src, fd2, dst, flags);
- if (! (r < 0 && (errno == ENOSYS || errno == EINVAL)))
- return r;
+ ret_val = syscall (SYS_renameat2, fd1, src, fd2, dst, flags);
+ err = errno;
+#elif defined RENAME_EXCL
+ if (! (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE)))
+ {
+ ret_val = renameatx_np (fd1, src, fd2, dst,
+ ((flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)
+ | (flags & RENAME_NOREPLACE ? RENAME_EXCL : 0)));
+ err = errno;
+ }
#endif

+ if (! (ret_val < 0 && (err == EINVAL || err == ENOSYS || err == ENOTSUP)))
+ return ret_val;
+
#if HAVE_RENAMEAT
{
size_t src_len;
@@ -88,7 +101,6 @@ renameat2 (int fd1, char const *src, int fd2, char const *dst,
char *dst_temp = (char *) dst;
bool src_slash;
bool dst_slash;
- int ret_val;
int rename_errno = ENOTDIR;
struct stat src_st;
struct stat dst_st;
--
2.13.5
Loading...