[libc-commits] [libc] c04807c - [libc][c11] Add stdio.h's rename() function (#85068)
via libc-commits
libc-commits at lists.llvm.org
Thu Mar 21 08:21:12 PDT 2024
Author: aniplcc
Date: 2024-03-21T08:21:06-07:00
New Revision: c04807c84e2a2653ab325f1b8ec73916565e6c54
URL: https://github.com/llvm/llvm-project/commit/c04807c84e2a2653ab325f1b8ec73916565e6c54
DIFF: https://github.com/llvm/llvm-project/commit/c04807c84e2a2653ab325f1b8ec73916565e6c54.diff
LOG: [libc][c11] Add stdio.h's rename() function (#85068)
Adds stdio.h's rename() function as defined in n3096. Fixes #84980.
Added:
libc/src/stdio/linux/rename.cpp
libc/src/stdio/rename.h
libc/test/src/stdio/rename_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/riscv/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/docs/stdio.rst
libc/spec/stdc.td
libc/src/stdio/CMakeLists.txt
libc/src/stdio/linux/CMakeLists.txt
libc/test/src/stdio/CMakeLists.txt
utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index dbf81c284e7845..6abb35ab0ead70 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -195,6 +195,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# stdio.h entrypoints
libc.src.stdio.remove
+ libc.src.stdio.rename
libc.src.stdio.sprintf
libc.src.stdio.snprintf
libc.src.stdio.vsprintf
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index b42a55a4d712e1..e34c87ec6b5d34 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -196,6 +196,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# stdio.h entrypoints
libc.src.stdio.remove
+ libc.src.stdio.rename
libc.src.stdio.sprintf
libc.src.stdio.snprintf
libc.src.stdio.fprintf
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c216f43496270b..8e1ab5cd65f005 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -198,6 +198,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# stdio.h entrypoints
libc.src.stdio.remove
+ libc.src.stdio.rename
libc.src.stdio.sprintf
libc.src.stdio.snprintf
libc.src.stdio.fprintf
diff --git a/libc/docs/stdio.rst b/libc/docs/stdio.rst
index 4fd6b71a09171b..d17821562c2556 100644
--- a/libc/docs/stdio.rst
+++ b/libc/docs/stdio.rst
@@ -68,7 +68,7 @@ These functions operate on files on the host's system, without using the
Function_Name Available
============= =========
remove |check|
-rename
+rename |check|
tmpnam
============= =========
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 920036adfed5c1..76010a4b4533a7 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -706,6 +706,11 @@ def StdC : StandardSpec<"stdc"> {
RetValSpec<IntType>,
[ArgSpec<ConstCharPtr>]
>,
+ FunctionSpec<
+ "rename",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>]
+ >,
FunctionSpec<
"setbuf",
RetValSpec<VoidType>,
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index ece93fd56ef0c5..11e15c91735188 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -256,6 +256,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.remove
)
+add_entrypoint_object(
+ rename
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.rename
+)
+
# These entrypoints have multiple potential implementations.
add_stdio_entrypoint_object(feof)
add_stdio_entrypoint_object(feof_unlocked)
diff --git a/libc/src/stdio/linux/CMakeLists.txt b/libc/src/stdio/linux/CMakeLists.txt
index 774f24b2db0bdc..a08ff0ba4832ff 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -12,3 +12,15 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
+
+add_entrypoint_object(
+ rename
+ SRCS
+ rename.cpp
+ HDRS
+ ../rename.h
+ DEPENDS
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
diff --git a/libc/src/stdio/linux/rename.cpp b/libc/src/stdio/linux/rename.cpp
new file mode 100644
index 00000000000000..f3d684249ad28e
--- /dev/null
+++ b/libc/src/stdio/linux/rename.cpp
@@ -0,0 +1,26 @@
+//===-- Linux implementation of rename ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/rename.h"
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_rename, oldpath, newpath);
+
+ if (ret >= 0)
+ return 0;
+ libc_errno = -ret;
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdio/rename.h b/libc/src/stdio/rename.h
new file mode 100644
index 00000000000000..eadda7c3eac9b6
--- /dev/null
+++ b/libc/src/stdio/rename.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of rename -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_RENAME_H
+#define LLVM_LIBC_SRC_STDIO_RENAME_H
+
+namespace LIBC_NAMESPACE {
+
+int rename(const char *oldpath, const char *newpath);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_STDIO_RENAME_H
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index 3ccce16a76a2d5..a11a232c27e1a7 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -354,6 +354,21 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
libc.src.unistd.access
libc.src.unistd.close
)
+
+ add_libc_test(
+ rename_test
+ SUITE
+ libc_stdio_unittests
+ SRCS
+ rename_test.cpp
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.fcntl.open
+ libc.src.stdio.rename
+ libc.src.unistd.access
+ libc.src.unistd.close
+ libc.test.UnitTest.ErrnoSetterMatcher
+ )
endif()
add_libc_test(
diff --git a/libc/test/src/stdio/rename_test.cpp b/libc/test/src/stdio/rename_test.cpp
new file mode 100644
index 00000000000000..a9fbe24ded9cf7
--- /dev/null
+++ b/libc/test/src/stdio/rename_test.cpp
@@ -0,0 +1,49 @@
+//===-- Unittests for rename ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/fcntl/open.h"
+#include "src/stdio/rename.h"
+#include "src/unistd/access.h"
+#include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcRenameTest, CreateAndRenameFile) {
+ // The test strategy is to create a file and rename it, and also verify that
+ // it was renamed.
+ LIBC_NAMESPACE::libc_errno = 0;
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+ constexpr const char *FILENAME0 = "rename.test.file0";
+ auto TEST_FILEPATH0 = libc_make_test_file_path(FILENAME0);
+
+ int fd = LIBC_NAMESPACE::open(TEST_FILEPATH0, O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GT(fd, 0);
+ ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Succeeds(0));
+
+ constexpr const char *FILENAME1 = "rename.test.file1";
+ auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
+ ASSERT_THAT(LIBC_NAMESPACE::rename(TEST_FILEPATH0, TEST_FILEPATH1),
+ Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH1, F_OK), Succeeds(0));
+ ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Fails(ENOENT));
+}
+
+TEST(LlvmLibcRenameTest, RenameNonExistent) {
+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+
+ constexpr const char *FILENAME1 = "rename.test.file1";
+ auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
+
+ ASSERT_THAT(LIBC_NAMESPACE::rename("non-existent", TEST_FILEPATH1),
+ Fails(ENOENT));
+}
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 40cfb1f470dbec..fe4b8e2de14e66 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3262,6 +3262,17 @@ libc_function(
],
)
+libc_function(
+ name = "rename",
+ srcs = ["src/stdio/linux/rename.cpp"],
+ hdrs = ["src/stdio/rename.h"],
+ deps = [
+ ":__support_common",
+ ":__support_osutil_syscall",
+ ":errno",
+ ],
+)
+
############################### sys/stat targets ###############################
libc_function(
More information about the libc-commits
mailing list