Hi, On Fri, Sep 21, 2018 at 04:42:37PM -0700, Paul Eggert wrote: > Johannes Schauer wrote: > > This problem could be solved by coreutils using the glibc renameat2 > > function in > > glibc version 2.28 and newer. > > Yes, that's on my list of things to do. It's not high priority, though, so > if you want it done faster you can write up and test the code and submit a > patch (hint, hint). >
Probably going to embarras myself here with no prior coreutils (or gnulib) experience and including an untested patch, but oh well. I tried to look at this issue and AIUI this is basically a gnulib issue rather than coreutils. There's even been some relevant changes done since (the gnulib version included in) coreutils 8.30: http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commit;h=2522322e5304e7d86c63e607e2bc83c8d8b0a889 Since I have no idea how to bundle a new gnulib version with coreutils to build a test version (and I don't even have glibc 2.28 yet either), I haven't been able to test but wouldn't a simple patch like the attached one do the trick? (Note: stdio.h is already included so no addition for it needed. The fallback discussed in [1] should be the same for HAVE_RENAMEAT2 and SYS_renameat2 codepaths.) [1] https://sourceware.org/ml/libc-alpha/2018-07/msg00064.html I assume if it was this simple you'd have already delt with it, so I'm probably way too naive here. Regards, Andreas Henriksson
>From 32e683687be271ba3589021722b14e54e8b41d08 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson <[email protected]> Date: Sat, 6 Oct 2018 20:25:24 +0200 Subject: [PATCH] renameatu: Use renameat2 when available Use the function call rather than direct syscall when possible. The renameat2 function is provided since glibc 2.28. See: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=32796 --- lib/renameatu.c | 5 ++++- m4/renameat.m4 | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/renameatu.c b/lib/renameatu.c index b013ad697..8a32417bf 100644 --- a/lib/renameatu.c +++ b/lib/renameatu.c @@ -80,7 +80,10 @@ renameatu (int fd1, char const *src, int fd2, char const *dst, int ret_val = -1; int err = EINVAL; -#ifdef SYS_renameat2 +#ifdef HAVE_RENAMEAT2 + ret_val = renameat2(fd1, src, fd2, dst, flags); + err = errno; +#elif defined SYS_renameat2 ret_val = syscall (SYS_renameat2, fd1, src, fd2, dst, flags); err = errno; #elif defined RENAME_EXCL diff --git a/m4/renameat.m4 b/m4/renameat.m4 index 116750785..df6f1fd5a 100644 --- a/m4/renameat.m4 +++ b/m4/renameat.m4 @@ -16,6 +16,7 @@ AC_DEFUN([gl_FUNC_RENAMEAT], AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_HEADERS([linux/fs.h]) AC_CHECK_FUNCS_ONCE([renameat]) + AC_CHECK_FUNCS_ONCE([renameat2]) if test $ac_cv_func_renameat = no; then HAVE_RENAMEAT=0 elif test $REPLACE_RENAME = 1; then -- 2.19.0
