]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Add renameat2 function [BZ #17662]
authorFlorian Weimer <fweimer@redhat.com>
Thu, 5 Jul 2018 16:59:02 +0000 (18:59 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 5 Jul 2018 17:00:10 +0000 (19:00 +0200)
The implementation falls back to renameat if renameat2 is not available
in the kernel (or in the kernel headers) and the flags argument is zero.
Without kernel support, a non-zero argument returns EINVAL, not ENOSYS.
This mirrors what the kernel does for invalid renameat2 flags.

45 files changed:
ChangeLog
NEWS
include/stdio.h
libio/stdio.h
manual/filesys.texi
stdio-common/Makefile
stdio-common/Versions
stdio-common/renameat.c
stdio-common/renameat2.c [new file with mode: 0644]
stdio-common/tst-renameat2.c [new file with mode: 0644]
sysdeps/mach/hurd/i386/libc.abilist
sysdeps/mach/hurd/renameat.c
sysdeps/unix/sysv/linux/aarch64/libc.abilist
sysdeps/unix/sysv/linux/alpha/kernel-features.h
sysdeps/unix/sysv/linux/alpha/libc.abilist
sysdeps/unix/sysv/linux/arm/libc.abilist
sysdeps/unix/sysv/linux/hppa/libc.abilist
sysdeps/unix/sysv/linux/i386/libc.abilist
sysdeps/unix/sysv/linux/ia64/libc.abilist
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
sysdeps/unix/sysv/linux/microblaze/kernel-features.h
sysdeps/unix/sysv/linux/microblaze/libc.abilist
sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
sysdeps/unix/sysv/linux/nios2/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
sysdeps/unix/sysv/linux/renameat.c
sysdeps/unix/sysv/linux/renameat2.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
sysdeps/unix/sysv/linux/sh/kernel-features.h
sysdeps/unix/sysv/linux/sh/libc.abilist
sysdeps/unix/sysv/linux/sparc/kernel-features.h
sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

index 2e8308e19192b878d96771a445e7357a3cc855d7..27927257ceb6391a239ab8181d083a968f75e18b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2018-07-05  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ # 17662]
+       * libio/stdio.h [__USE_GNU] (RENAME_NOREPLACE, RENAME_EXCHANGE)
+       (RENAME_WHITEOUT): Define.
+       [__USE_GNU] (renameat2): Declare.
+       * stdio-common/Makefile (routines): Add renameat2.
+       (tests): Add tst-renameat2.
+       * stdio-common/Versions (GLIBC_2_28): Export renameat2.
+       * stdio-common/renameat2.c: New file.
+       * stdio-common/tst-renameat2.c: Likewise.
+       * sysdeps/unix/sysv/linux/renameat2.c: Likewise.
+       * manual/filesys.texi (Temporary Files): Note that renameat2 is
+       undocumented.
+       * sysdeps/unix/sysv/linux/kernel-features.h
+       [__LINUX_KERNEL_VERSION >= 0x030F00] (__ASSUME_RENAMEAT2): Define.
+       * sysdeps/unix/sysv/linux/alpha/kernel-features.h
+       [__LINUX_KERNEL_VERSION < 0x031100] (__ASSUME_RENAMEAT2): Undefine.
+       * sysdeps/unix/sysv/linux/microblaze/kernel-features.h
+       [__LINUX_KERNEL_VERSION < 0x031100] (__ASSUME_RENAMEAT2): Undefine.
+       * sysdeps/unix/sysv/linux/sh/kernel-features.h
+       [__LINUX_KERNEL_VERSION < 0x040800] (__ASSUME_RENAMEAT2): Undefine.
+       * sysdeps/unix/sysv/linux/sparc/kernel-features.h
+       [__LINUX_KERNEL_VERSION < 0x031000] (__ASSUME_RENAMEAT2): Undefine.
+       * include/stdio.h (__renameat): Add alias for renameat.
+       * stdio-common/renameat.c (__renameat): Rename from renameat.
+       Add hidden definition and alias.
+       * sysdeps/unix/sysv/linux/renameat.c: Likewise.
+       * sysdeps/mach/hurd/renameat.c: Likewise.
+       * sysdeps/**/libc*.abilist: Add renameat2.
+
 2018-07-04  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
        * posix/bug-regex33.c: Fix build after regex sync.
diff --git a/NEWS b/NEWS
index b1ce067d27cab22f75108ffea4962f713aacf268..5d253910b571577b6d4fccf3a66b02cdec9fe193 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,15 @@ Major new features:
 * Building and running on GNU/Hurd systems now works without out-of-tree
   patches.
 
+* The renameat2 function has been added, a variant of the renameat function
+  which has a flags argument.  If the flags are zero, the renameat2 function
+  acts like renameat.  If the flag is not zero and there is no kernel
+  support for renameat2, the function will fail with an errno value of
+  EINVAL.  This is different from the existing gnulib function renameatu,
+  which performs a plain rename operation in case of a RENAME_NOREPLACE
+  flags and a non-existing destination (and therefore has a race condition
+  that can clobber the destination inadvertently).
+
 * IDN domain names in getaddrinfo and getnameinfo now use the system libidn2
   library if installed.  libidn2 version 2.0.5 or later is recommended.  If
   libidn2 is not available, internationalized domain names are not encoded
index f140813ad6bc0e916dab39797454cdbd1c101ed6..3ba0edc924267947c91f4f4e369f356ad5f59266 100644 (file)
@@ -237,5 +237,8 @@ __putc_unlocked (int __c, FILE *__stream)
 }
 #  endif
 
+extern __typeof (renameat) __renameat;
+libc_hidden_proto (__renameat)
+
 # endif /* not _ISOMAC */
 #endif /* stdio.h */
index 731f8e56f4c115a1a507b85babaa22b21efb140c..739e08610d54f341cf14247ec38f254e1520e5b1 100644 (file)
@@ -153,6 +153,18 @@ extern int renameat (int __oldfd, const char *__old, int __newfd,
                     const char *__new) __THROW;
 #endif
 
+#ifdef __USE_GNU
+/* Flags for renameat2.  */
+# define RENAME_NOREPLACE (1 << 0)
+# define RENAME_EXCHANGE (1 << 1)
+# define RENAME_WHITEOUT (1 << 2)
+
+/* Rename file OLD relative to OLDFD to NEW relative to NEWFD, with
+   additional flags.  */
+extern int renameat2 (int __oldfd, const char *__old, int __newfd,
+                     const char *__new, unsigned int __flags) __THROW;
+#endif
+
 /* Create a temporary file and open it read/write.
 
    This function is a possible cancellation point and therefore not
index cc70a6b7eebddc8d1c34d658592504c446579ad3..db2f1041de077a1d325c570c993ed2fb75228775 100644 (file)
@@ -3552,6 +3552,7 @@ The @code{mkdtemp} function comes from OpenBSD.
 @c open_by_handle_at
 @c readlinkat
 @c renameat
+@c renameat2
 @c scandirat
 @c symlinkat
 @c unlinkat
index 96bd7c303a15b989c59f1d693ef1dbbe2884a106..a10f12ab3ccbd76e43ee8929672ec74b6899f501 100644 (file)
@@ -35,7 +35,7 @@ routines      :=                                                            \
        perror psignal                                                        \
        tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname                    \
        getline getw putw                                                     \
-       remove rename renameat                                                \
+       remove rename renameat renameat2                                      \
        flockfile ftrylockfile funlockfile                                    \
        isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \
        isoc99_vsscanf                                                        \
@@ -62,6 +62,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
         tst-vfprintf-user-type \
         tst-vfprintf-mbs-prec \
         tst-scanf-round \
+        tst-renameat2 \
 
 test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
 
index 5016f69c206d49237b69355f823294946a9058c8..b8217578c8ef91392568e73f94c74c8bc6a432e0 100644 (file)
@@ -57,6 +57,9 @@ libc {
     psiginfo;
     register_printf_modifier; register_printf_type; register_printf_specifier;
   }
+  GLIBC_2.28 {
+    renameat2;
+  }
   GLIBC_PRIVATE {
     # global variables
     _itoa_lower_digits;
index 2180b87bdfd689c26d784774513bfbe3feac80ed..98c8f1d18bd8012e3f6f44a15afd040a3dc39c9c 100644 (file)
@@ -22,7 +22,7 @@
 
 /* Rename the file OLD relative to OLDFD to NEW relative to NEWFD.  */
 int
-renameat (int oldfd, const char *old, int newfd, const char *new)
+__renameat (int oldfd, const char *old, int newfd, const char *new)
 {
   if ((oldfd < 0 && oldfd != AT_FDCWD) || (newfd < 0 && newfd != AT_FDCWD))
     {
@@ -40,5 +40,6 @@ renameat (int oldfd, const char *old, int newfd, const char *new)
   return -1;
 }
 
-
+libc_hidden_def (__renameat)
+weak_alias (__renameat, renameat)
 stub_warning (renameat)
diff --git a/stdio-common/renameat2.c b/stdio-common/renameat2.c
new file mode 100644 (file)
index 0000000..c2cedcd
--- /dev/null
@@ -0,0 +1,30 @@
+/* Generic implementation of the renameat function.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdio.h>
+
+int
+renameat2 (int oldfd, const char *old, int newfd, const char *new,
+           unsigned int flags)
+{
+  if (flags == 0)
+    return __renameat (oldfd, old, newfd, new);
+  __set_errno (EINVAL);
+  return -1;
+}
diff --git a/stdio-common/tst-renameat2.c b/stdio-common/tst-renameat2.c
new file mode 100644 (file)
index 0000000..958b091
--- /dev/null
@@ -0,0 +1,204 @@
+/* Linux implementation for renameat2 function.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+/* Directory with the temporary files.  */
+static char *directory;
+static int directory_fd;
+
+/* Paths within that directory.  */
+static char *old_path;          /* File is called "old".  */
+static char *new_path;          /* File is called "new".  */
+
+/* Subdirectory within the directory above.  */
+static char *subdirectory;
+int subdirectory_fd;
+
+/* And a pathname in that directory (called "file").  */
+static char *subdir_path;
+
+static void
+prepare (int argc, char **argv)
+{
+  directory = support_create_temp_directory ("tst-renameat2-");
+  directory_fd = xopen (directory, O_RDONLY | O_DIRECTORY, 0);
+  old_path = xasprintf ("%s/old", directory);
+  add_temp_file (old_path);
+  new_path = xasprintf ("%s/new", directory);
+  add_temp_file (new_path);
+  subdirectory = xasprintf ("%s/subdir", directory);
+  xmkdir (subdirectory, 0777);
+  add_temp_file (subdirectory);
+  subdirectory_fd = xopen (subdirectory, O_RDONLY | O_DIRECTORY, 0);
+  subdir_path = xasprintf ("%s/file", subdirectory);
+  add_temp_file (subdir_path);
+}
+
+/* Delete all files, preparing a clean slate for the next test.  */
+static void
+delete_all_files (void)
+{
+  char *files[] = { old_path, new_path, subdir_path };
+  for (size_t i = 0; i < array_length (files); ++i)
+    if (unlink (files[i]) != 0 && errno != ENOENT)
+      FAIL_EXIT1 ("unlink (\"%s\"): %m", files[i]);
+}
+
+/* Return true if PATH exists in the file system.  */
+static bool
+file_exists (const char *path)
+{
+  return access (path, F_OK) == 0;
+}
+
+/* Check that PATH exists and has size EXPECTED_SIZE.  */
+static void
+check_size (const char *path, off64_t expected_size)
+{
+  struct stat64 st;
+  xstat (path, &st);
+  if (st.st_size != expected_size)
+    FAIL_EXIT1 ("file \"%s\": expected size %lld, actual size %lld",
+                path, (unsigned long long int) expected_size,
+                (unsigned long long int) st.st_size);
+}
+
+/* Rename tests where the target does not exist.  */
+static void
+rename_without_existing_target (unsigned int flags)
+{
+  delete_all_files ();
+  support_write_file_string (old_path, "");
+  TEST_COMPARE (renameat2 (AT_FDCWD, old_path, AT_FDCWD, new_path, flags), 0);
+  TEST_VERIFY (!file_exists (old_path));
+  TEST_VERIFY (file_exists (new_path));
+
+  delete_all_files ();
+  support_write_file_string (old_path, "");
+  TEST_COMPARE (renameat2 (directory_fd, "old", AT_FDCWD, new_path, flags), 0);
+  TEST_VERIFY (!file_exists (old_path));
+  TEST_VERIFY (file_exists (new_path));
+
+  delete_all_files ();
+  support_write_file_string (old_path, "");
+  TEST_COMPARE (renameat2 (directory_fd, "old", subdirectory_fd, "file", 0),
+                0);
+  TEST_VERIFY (!file_exists (old_path));
+  TEST_VERIFY (file_exists (subdir_path));
+}
+
+static int
+do_test (void)
+{
+  /* Tests with zero flags argument.  These are expected to succeed
+     because this renameat2 variant can be implemented with
+     renameat.  */
+  rename_without_existing_target (0);
+
+  /* renameat2 without flags replaces an existing destination.  */
+  delete_all_files ();
+  support_write_file_string (old_path, "123");
+  support_write_file_string (new_path, "1234");
+  TEST_COMPARE (renameat2 (AT_FDCWD, old_path, AT_FDCWD, new_path, 0), 0);
+  TEST_VERIFY (!file_exists (old_path));
+  check_size (new_path, 3);
+
+  /* Now we need to check for kernel support of renameat2 with
+     flags.  */
+  delete_all_files ();
+  support_write_file_string (old_path, "");
+  if (renameat2 (AT_FDCWD, old_path, AT_FDCWD, new_path, RENAME_NOREPLACE)
+      != 0)
+    {
+      if (errno == EINVAL)
+        puts ("warning: no support for renameat2 with flags");
+      else
+        FAIL_EXIT1 ("renameat2 probe failed: %m");
+    }
+  else
+    {
+      /* We have full renameat2 support.  */
+      rename_without_existing_target (RENAME_NOREPLACE);
+
+      /* Now test RENAME_NOREPLACE with an existing target.  */
+      delete_all_files ();
+      support_write_file_string (old_path, "123");
+      support_write_file_string (new_path, "1234");
+      TEST_COMPARE (renameat2 (AT_FDCWD, old_path, AT_FDCWD, new_path,
+                               RENAME_NOREPLACE), -1);
+      TEST_COMPARE (errno, EEXIST);
+      check_size (old_path, 3);
+      check_size (new_path, 4);
+
+      delete_all_files ();
+      support_write_file_string (old_path, "123");
+      support_write_file_string (new_path, "1234");
+      TEST_COMPARE (renameat2 (directory_fd, "old", AT_FDCWD, new_path,
+                               RENAME_NOREPLACE), -1);
+      TEST_COMPARE (errno, EEXIST);
+      check_size (old_path, 3);
+      check_size (new_path, 4);
+
+      delete_all_files ();
+      support_write_file_string (old_path, "123");
+      support_write_file_string (subdir_path, "1234");
+      TEST_COMPARE (renameat2 (directory_fd, "old", subdirectory_fd, "file",
+                               RENAME_NOREPLACE), -1);
+      TEST_COMPARE (errno, EEXIST);
+      check_size (old_path, 3);
+      check_size (subdir_path, 4);
+
+      /* The flag combination of RENAME_NOREPLACE and RENAME_EXCHANGE
+         is invalid.  */
+      TEST_COMPARE (renameat2 (directory_fd, "ignored",
+                               subdirectory_fd, "ignored",
+                               RENAME_NOREPLACE | RENAME_EXCHANGE), -1);
+      TEST_COMPARE (errno, EINVAL);
+    }
+
+  /* Create all the pathnames to avoid warnings from the test
+     harness.  */
+  support_write_file_string (old_path, "");
+  support_write_file_string (new_path, "");
+  support_write_file_string (subdir_path, "");
+
+  free (directory);
+  free (subdirectory);
+  free (old_path);
+  free (new_path);
+  free (subdir_path);
+
+  xclose (directory_fd);
+  xclose (subdirectory_fd);
+
+  return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>
index 57091fce00134a4dad5232fea170d2d87de6591b..a9089d90646f165b661c73e438502a61f0f48ea4 100644 (file)
@@ -2034,6 +2034,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 43609600d9ac48d8618757c000ce88c1d484a249..7985763f73ea066518bd201c4013faf704ee2075 100644 (file)
@@ -22,7 +22,7 @@
 
 /* Rename the file OLD relative to OLDFD to NEW relative to NEWFD.  */
 int
-renameat (int oldfd, const char *old, int newfd, const char *new)
+__renameat (int oldfd, const char *old, int newfd, const char *new)
 {
   error_t err;
   file_t olddir, newdir;
@@ -45,3 +45,5 @@ renameat (int oldfd, const char *old, int newfd, const char *new)
     return __hurd_fail (err);
   return 0;
 }
+libc_hidden_def (__renameat)
+weak_alias (__renameat, renameat)
index 884d0dfa95cd523701d943d8c0805c390bd15660..7a272a19bb5d819554d937fc4436e2d31555e313 100644 (file)
@@ -2132,3 +2132,4 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
index c2d4a9f55b8aa2e0da21c82bf110ae8182720c8f..5781cffd5ac4d782082f6696b2ba715f9e71a37a 100644 (file)
 #define __ASSUME_RECV_SYSCALL  1
 #define __ASSUME_SEND_SYSCALL  1
 
+/* Support for the renameat2 syscall was added in 3.17.  */
+#if __LINUX_KERNEL_VERSION < 0x031100
+# undef __ASSUME_RENAMEAT2
+#endif
+
 /* Support for the execveat syscall was added in 4.2.  */
 #if __LINUX_KERNEL_VERSION < 0x040200
 # undef __ASSUME_EXECVEAT
index 28d54b97949638822870297e1c1be650c4ab0988..23fec55d977dd4bd5e12dcfba58a1b5c415b5a75 100644 (file)
@@ -2027,6 +2027,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index dfde3bd7258ce3f98b7b4d8f185ef8c27ff265e9..b2031608896297cb90ded5ad6a11160b7f3b591c 100644 (file)
@@ -117,6 +117,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
index 06b00f730a7270d7abeef3c9147a616d1732273c..64809ca4032b1eabc768095f091bb1a046262127 100644 (file)
@@ -1874,6 +1874,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 1c1cc00d4020f027f30a9b87027df280dce9498d..4a87f62ad97e6f1e3564e139cd6fd8adfe9d96ba 100644 (file)
@@ -2039,6 +2039,7 @@ GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index f6e17a005f6023ba9c1864b2adc6fce2c9d978b2..6bdd0d0443b86ea1766dba5f9604a37ff08ad112 100644 (file)
@@ -1908,6 +1908,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index b90ea30195e8e8227cfde04f85d0527557bbb947..86fc66574b6851d398708973bae5b9472a9d8de0 100644 (file)
    implementation based on p{read,write}v and returning an error for
    non supported flags.  */
 
+/* Support for the renameat2 system call was added in kernel 3.15.  */
+#if __LINUX_KERNEL_VERSION >= 0x030F00
+# define __ASSUME_RENAMEAT2
+#endif
+
 /* Support for the execveat syscall was added in 3.19.  */
 #if __LINUX_KERNEL_VERSION >= 0x031300
 # define __ASSUME_EXECVEAT     1
index ee054a618d36cde3ac0f367b25f83db51bbfaaaa..3226f916eb99e9f00dd7f095926a3310af0155a2 100644 (file)
@@ -118,6 +118,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
index 227a0581cbfc690add22fb8c6039a4d8b95c610e..b1074eeed133deb0385edb5c8e96bd4dc7109b5b 100644 (file)
@@ -1983,6 +1983,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index b13b863f061c6e40391fbb72015b841c9e21ceba..7db3d05636f3c1c4d63ed8c8c9d603bf996fb1b1 100644 (file)
 # undef __ASSUME_SENDMMSG_SYSCALL
 #endif
 
+/* Support for the renameat2 syscall was added in 3.17.  */
+#if __LINUX_KERNEL_VERSION < 0x031100
+# undef __ASSUME_RENAMEAT2
+#endif
+
 /* Support for the execveat syscall was added in 4.0.  */
 #if __LINUX_KERNEL_VERSION < 0x040000
 # undef __ASSUME_EXECVEAT
index 18781b30171e65e8d04953e27b95e90affeaba81..b52fc7d6f796111bc7acb7a44406deab222577bb 100644 (file)
@@ -2124,3 +2124,4 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
index 2d86989cf26a7710912c011ba31d0331401397c2..718c74262ad1883e3263ccaed0857bf8620369d4 100644 (file)
@@ -1961,6 +1961,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index b8b113e1a5085a695ba2adef2d302ccb55239026..9b218a9435449d435d22b414dbcd220efeed85e5 100644 (file)
@@ -1959,6 +1959,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 6a3cd13e2d8d9bf4c008a63cb1f391172d4ce8d0..5a90ab83e7b449a6355794265a0010565c02964b 100644 (file)
@@ -1967,6 +1967,7 @@ GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 596ec05379fefe6ba8c4ff4e6e98ba724acfc280..3005fc9500f8c7c661a6b4bab5edf363f17ef91d 100644 (file)
@@ -1962,6 +1962,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 8da18eed57424cf7b76d4683fc8e4ae3938b50f7..a87fbbeb6be02f7772c549ac019857ab87d45054 100644 (file)
@@ -2165,3 +2165,4 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
index 555751eb12a0cb9811c4c05957e62b6e65114d9c..d56f776a52bce613c2632defe475288d99b11b7e 100644 (file)
@@ -1987,6 +1987,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 80324e41aab49b9b11644c010fc6732a82604123..2b5337aab631166688c7f79be78d6059790b69d0 100644 (file)
@@ -1991,6 +1991,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 97b1d354afc479b298ff89eaadfbc87f1597371d..d0dfde389718e2e386b43d7829a081b2e6f2e6ae 100644 (file)
@@ -2222,3 +2222,4 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
index 15be314921bb8d4ceea64bdffac55782b409db96..d505ae0e7dd48f11744de682e31f97858138e47d 100644 (file)
@@ -117,6 +117,7 @@ GLIBC_2.27 wcstof32x_l F
 GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
 GLIBC_2.3 _IO_2_1_stdin_ D 0xe0
index 034432b934b8e6b149c9ef362db6d847ee718c7d..f85c5ae0ec3cb8593c4a8dbfeb854394565e812f 100644 (file)
@@ -22,7 +22,7 @@
 #include <errno.h>
 
 int
-renameat (int oldfd, const char *old, int newfd, const char *new)
+__renameat (int oldfd, const char *old, int newfd, const char *new)
 {
 #ifdef __NR_renameat
   return INLINE_SYSCALL_CALL (renameat, oldfd, old, newfd, new);
@@ -30,3 +30,5 @@ renameat (int oldfd, const char *old, int newfd, const char *new)
   return INLINE_SYSCALL_CALL (renameat2, oldfd, old, newfd, new, 0);
 #endif
 }
+libc_hidden_def (__renameat)
+weak_alias (__renameat, renameat)
diff --git a/sysdeps/unix/sysv/linux/renameat2.c b/sysdeps/unix/sysv/linux/renameat2.c
new file mode 100644 (file)
index 0000000..919bb2a
--- /dev/null
@@ -0,0 +1,44 @@
+/* Linux implementation for renameat2 function.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sysdep.h>
+
+int
+renameat2 (int oldfd, const char *old, int newfd, const char *new,
+           unsigned int flags)
+{
+#if !defined (__NR_renameat) || defined (__ASSUME_RENAMEAT2)
+  return INLINE_SYSCALL_CALL (renameat2, oldfd, old, newfd, new, flags);
+#else
+  if (flags == 0)
+    return __renameat (oldfd, old, newfd, new);
+# ifdef __NR_renameat2
+  /* For non-zero flags, try the renameat2 system call.  */
+  int ret = INLINE_SYSCALL_CALL (renameat2, oldfd, old, newfd, new, flags);
+  if (ret != -1 || errno != ENOSYS)
+    /* Preserve non-error/non-ENOSYS return values.  */
+    return ret;
+# endif
+  /* No kernel (header) support for renameat2.  All flags are
+     unknown.  */
+  __set_errno (EINVAL);
+  return -1;
+#endif
+}
index 436b9922512bd0383768731fbeacb1d4ef036dc4..33f751abc0bbd7ab15bd210bf741e7071ae1b8d6 100644 (file)
@@ -2094,3 +2094,4 @@ GLIBC_2.27 xencrypt F
 GLIBC_2.27 xprt_register F
 GLIBC_2.27 xprt_unregister F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
index f66715f0c959bcf97206ad4fd44b5b117f4e7e0d..c4ec93ff43fc5948ff9f19422c3010e31189c343 100644 (file)
@@ -1996,6 +1996,7 @@ GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index bd6242861b44b10418b0ef554854662da5fd582a..2a6a0abde85c5e422165768d9cde1ce80f187f87 100644 (file)
@@ -1901,6 +1901,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index b82d032e6b8a428b37ee2975b3d46b86532ee45a..05b7dcd0372fadc538c6ec95003f468d21a9f2c7 100644 (file)
@@ -51,4 +51,9 @@
 /* sh only supports ipc syscall.  */
 #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
 
+/* Support for the renameat2 syscall was added in 4.8.  */
+#if __LINUX_KERNEL_VERSION < 0x040800
+# undef __ASSUME_RENAMEAT2
+#endif
+
 #endif
index f2f070fbceea1ac758495fe2704387175127c05d..8de0d1711a30c1756f572819d92ff912415c4057 100644 (file)
@@ -1878,6 +1878,7 @@ GLIBC_2.27 wcstof64 F
 GLIBC_2.27 wcstof64_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 64d714036ed4fd35f30b830d8e62c8c2a2519598..91990a716fa8be5b2f400eea19116ad72260a231 100644 (file)
 /* sparc only supports ipc syscall.  */
 #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
 
+/* Support for the renameat2 syscall was added in 3.16.  */
+#if __LINUX_KERNEL_VERSION < 0x031000
+# undef __ASSUME_RENAMEAT2
+#endif
+
 /* SPARC kernel Kconfig does not define CONFIG_CLONE_BACKWARDS, however it
    has the same ABI as if it did, implemented by sparc-specific code
    (sparc_do_fork).
index 265087f6a813b7d1322f34136625d77a009b5e56..9858460c9fffd2a94c7deaf2b3219d2f298d07ac 100644 (file)
@@ -1990,6 +1990,7 @@ GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 16a69812cbc68555e86b4595706d216c661d919c..a22b8fb7cafcb1a0f1cf963fd9af51768d8e6928 100644 (file)
@@ -1931,6 +1931,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index fa8c198d1350e5d1d629470e39b595db558d1aee..d5d71cccbac87e2db95eb790347ac69e3dc99321 100644 (file)
@@ -1889,6 +1889,7 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
 GLIBC_2.3 __ctype_toupper_loc F
index 2536971682ac2e3bdad0061e6307763b358f4b62..e6ad42440e1ed2d7e3ce2734577c899afd9502e0 100644 (file)
@@ -2140,3 +2140,4 @@ GLIBC_2.27 wcstof64_l F
 GLIBC_2.27 wcstof64x F
 GLIBC_2.27 wcstof64x_l F
 GLIBC_2.28 fcntl64 F
+GLIBC_2.28 renameat2 F