From 9abc08406d458ce18eb98a286aaae618a33dd231 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 15 Aug 2017 17:09:35 -0700 Subject: [PATCH] renameat2: port better to macOS * 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 bc0c169911..e4fe8dd61a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2017-08-15 Paul Eggert + 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 fd38a71e7f..1e107fc500 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.39.5