From patchwork Sat Jun 30 12:14:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 937406 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-93872-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="BEbtMK4t"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41HssS4XhNz9ry1 for ; Sat, 30 Jun 2018 22:15:07 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; q=dns; s=default; b= bQOph69jxf8DNtOMLkO9p6y1N6EbHgUjf/NkhD44xzufMS852tE+x7aEHKhwaUrU VKhiVvwW/DC08oiGEurkO9N9R5wcEpNlCJ4BPk4nI3zohfKP4otP0eDYZ+3e0Bot V6AI5EdYPEaI2XIo7zdckuLrPouAEEnaYC+FAcWzC50= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; s=default; bh=5yZL12 BZoMq2bO5E8N4834RBABk=; b=BEbtMK4teCIZX/FHRCmdRGk7ulviwvkkNQeuHh 5K42ul3gjI5TeZSJ4mse3WOxHLfzHzJ684Wa7ZnHICN5lppYRk59uZaZaMctLUII uFXzG2lSP5H08ztNl9ePmkjT7UTMYi7ECSms3AwNuyLVtnjsbXfNgMKSnG0x9VsZ l3bVw= Received: (qmail 72853 invoked by alias); 30 Jun 2018 12:15:00 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 72817 invoked by uid 89); 30 Jun 2018 12:14:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=slate, harness, OLD X-HELO: mx1.redhat.com Date: Sat, 30 Jun 2018 14:14:47 +0200 To: libc-alpha@sourceware.org Subject: [PATCH] Add renameat2 function [BZ #17662] User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20180630121447.E4C8643994575@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) 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. 2018-06-30 Florian Weimer [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. * 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. Signed-off-by: Yury Norov Reviewed-by: Carlos O'Donell Reviewed-by: Carlos O'Donell diff --git a/NEWS b/NEWS index a27dd371a3..093f364c7e 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,8 @@ Major new features: * Building and running on GNU/Hurd systems now works without out-of-tree patches. +* The renameat2 function has been added. + * 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 diff --git a/include/stdio.h b/include/stdio.h index f140813ad6..3ba0edc924 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -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 */ diff --git a/libio/stdio.h b/libio/stdio.h index 731f8e56f4..3cdc8cc532 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -153,6 +153,18 @@ extern int renameat (int __oldfd, const char *__old, int __newfd, const char *__new) __THROW; #endif +#ifdef __USE_GNU +/* Flags for renameat. */ +# 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 diff --git a/manual/filesys.texi b/manual/filesys.texi index cc70a6b7ee..db2f1041de 100644 --- a/manual/filesys.texi +++ b/manual/filesys.texi @@ -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 diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 738a3cead0..6fd628708f 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -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 diff --git a/stdio-common/Versions b/stdio-common/Versions index 5016f69c20..b8217578c8 100644 --- a/stdio-common/Versions +++ b/stdio-common/Versions @@ -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; diff --git a/stdio-common/renameat.c b/stdio-common/renameat.c index 2180b87bdf..98c8f1d18b 100644 --- a/stdio-common/renameat.c +++ b/stdio-common/renameat.c @@ -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 index 0000000000..c2cedcd2cb --- /dev/null +++ b/stdio-common/renameat2.c @@ -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 + . */ + +#include +#include + +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 index 0000000000..958b0918d6 --- /dev/null +++ b/stdio-common/tst-renameat2.c @@ -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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 3d46de795d..9df86e491f 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2035,6 +2035,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 diff --git a/sysdeps/mach/hurd/renameat.c b/sysdeps/mach/hurd/renameat.c index 43609600d9..7985763f73 100644 --- a/sysdeps/mach/hurd/renameat.c +++ b/sysdeps/mach/hurd/renameat.c @@ -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) diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 884d0dfa95..7a272a19bb 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 28d54b9794..23fec55d97 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index dfde3bd725..b203160889 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 06b00f730a..64809ca403 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 1c1cc00d40..4a87f62ad9 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index f6e17a005f..6bdd0d0443 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index b90ea30195..ab42c5845a 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -144,3 +144,8 @@ */ #define __ASSUME_CLONE_DEFAULT 1 + +/* Support for the renameat2 system call was added in kernel 3.15. */ +#if __LINUX_KERNEL_VERSION >= 0x030F00 +# define __ASSUME_RENAMEAT2 +#endif diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index ee054a618d..3226f916eb 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 227a0581cb..b1074eeed1 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index 18781b3017..b52fc7d6f7 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 2d86989cf2..718c74262a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index b8b113e1a5..9b218a9435 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 6a3cd13e2d..5a90ab83e7 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 596ec05379..3005fc9500 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 8da18eed57..a87fbbeb6b 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 555751eb12..d56f776a52 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 80324e41aa..2b5337aab6 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index 97b1d354af..d0dfde3897 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index 15be314921..d505ae0e7d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/renameat.c b/sysdeps/unix/sysv/linux/renameat.c index 034432b934..f85c5ae0ec 100644 --- a/sysdeps/unix/sysv/linux/renameat.c +++ b/sysdeps/unix/sysv/linux/renameat.c @@ -22,7 +22,7 @@ #include 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 index 0000000000..919bb2a0d4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/renameat2.c @@ -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 + . */ + +#include +#include +#include + +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 +} diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 436b992251..33f751abc0 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index f66715f0c9..c4ec93ff43 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index bd6242861b..2a6a0abde8 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index f2f070fbce..8de0d1711a 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 265087f6a8..9858460c9f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 16a69812cb..a22b8fb7ca 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index fa8c198d13..d5d71cccba 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -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 diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 2536971682..e6ad42440e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -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