Add renameat2 function [BZ #17662]

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.
This commit is contained in:
Florian Weimer 2018-07-05 18:59:02 +02:00
parent 1002d70823
commit d6da5cb6a8
45 changed files with 400 additions and 5 deletions

View File

@ -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.

9
NEWS
View File

@ -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

View 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 */

View 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

View 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

View 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

View 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;

View 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)

30
stdio-common/renameat2.c Normal file
View File

@ -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;
}

View File

@ -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>

View 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

View 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)

View 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

View File

@ -35,6 +35,11 @@
#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

View 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

View 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

View 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

View 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

View 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

View File

@ -97,6 +97,11 @@
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

View 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

View 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

View File

@ -48,6 +48,11 @@
# 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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)

View File

@ -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
}

View 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

View 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

View 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

View 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

View 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

View File

@ -41,6 +41,11 @@
/* 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).

View 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

View 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

View 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

View 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