[libc-commits] [libc] [llvm] [libc][c11] Add stdio.h's rename() function (PR #85068)

via libc-commits libc-commits at lists.llvm.org
Wed Mar 13 05:47:04 PDT 2024


https://github.com/aniplcc updated https://github.com/llvm/llvm-project/pull/85068

>From e5a4492fd70a74dcf5bb6afc985a0ace08c00891 Mon Sep 17 00:00:00 2001
From: aniplcc <aniplccode at gmail.com>
Date: Wed, 13 Mar 2024 17:47:59 +0530
Subject: [PATCH 1/2] [libc][c11] Add stdio.h's rename() function

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 libc/config/linux/riscv/entrypoints.txt       |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/spec/stdc.td                             |  5 ++
 libc/src/stdio/CMakeLists.txt                 |  7 +++
 libc/src/stdio/linux/CMakeLists.txt           | 14 ++++++
 libc/src/stdio/linux/rename.cpp               | 38 ++++++++++++++
 libc/src/stdio/rename.h                       | 21 ++++++++
 libc/test/src/stdio/CMakeLists.txt            | 17 +++++++
 libc/test/src/stdio/rename_test.cpp           | 50 +++++++++++++++++++
 .../llvm-project-overlay/libc/BUILD.bazel     | 11 ++++
 11 files changed, 166 insertions(+)
 create mode 100644 libc/src/stdio/linux/rename.cpp
 create mode 100644 libc/src/stdio/rename.h
 create mode 100644 libc/test/src/stdio/rename_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index abd1f83794ed0b..5a4c9b850d46b2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -165,6 +165,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 006aa787ea6afd..35e8e01ab51b8c 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -166,6 +166,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 4fb31c593b9dc7..9e647842e1560a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -197,6 +197,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/spec/stdc.td b/libc/spec/stdc.td
index afe01b1bb68566..c52463f23c5069 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -695,6 +695,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 bb8e41606c5dfb..bc3e30239072f3 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -246,6 +246,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 3b5a9960dc125e..8579b86665b736 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -11,3 +11,17 @@ 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.fcntl
+    libc.include.unistd
+    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..d89f70af3cc593
--- /dev/null
+++ b/libc/src/stdio/linux/rename.cpp
@@ -0,0 +1,38 @@
+//===-- 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 <fcntl.h>       // For AT_* macros.
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
+#if defined(SYS_rename)
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_rename, oldpath, newpath);
+#elif defined(SYS_renameat)
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_renameat, AT_FDCWD, oldpath,
+                                              AT_FDCWD, newpath);
+#else
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_renameat2, AT_FDCWD, oldpath,
+                                              AT_FDCWD, newpath, 0);
+#endif
+
+  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..86a2e9912dcf63
--- /dev/null
+++ b/libc/src/stdio/rename.h
@@ -0,0 +1,21 @@
+//===-- 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
+
+#include <stdio.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 6e1c86e070a823..3c457f671dc701 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -355,6 +355,23 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
   )
 endif()
 
+if(${LIBC_TARGET_OS} STREQUAL "linux")
+  add_libc_test(
+    rename_test
+    SUITE
+      libc_stdio_unittests
+    SRCS
+      rename_test.cpp
+    DEPENDS
+      libc.include.unistd
+      libc.src.errno.errno
+      libc.src.fcntl.open
+      libc.src.stdio.rename
+      libc.src.unistd.access
+      libc.src.unistd.close
+  )
+endif()
+
 add_libc_test(
   fgetc_test
   SUITE
diff --git a/libc/test/src/stdio/rename_test.cpp b/libc/test/src/stdio/rename_test.cpp
new file mode 100644
index 00000000000000..f3b15bc83772c5
--- /dev/null
+++ b/libc/test/src/stdio/rename_test.cpp
@@ -0,0 +1,50 @@
+//===-- 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/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"
+
+#include "src/errno/libc_errno.h"
+#include <unistd.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 073353a89c8907..b91e3d24527102 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3230,6 +3230,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(

>From 9141a8e092de90bb3279c65ed223ff8986ae450a Mon Sep 17 00:00:00 2001
From: aniplcc <aniplccode at gmail.com>
Date: Wed, 13 Mar 2024 18:16:34 +0530
Subject: [PATCH 2/2] Add formatting fixes

---
 libc/src/stdio/linux/rename.cpp     | 1 -
 libc/src/stdio/rename.h             | 1 -
 libc/test/src/stdio/rename_test.cpp | 7 ++++---
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/libc/src/stdio/linux/rename.cpp b/libc/src/stdio/linux/rename.cpp
index d89f70af3cc593..c2d2aba9fd6a51 100644
--- a/libc/src/stdio/linux/rename.cpp
+++ b/libc/src/stdio/linux/rename.cpp
@@ -35,4 +35,3 @@ LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
 }
 
 } // namespace LIBC_NAMESPACE
-
diff --git a/libc/src/stdio/rename.h b/libc/src/stdio/rename.h
index 86a2e9912dcf63..17d67ec3df0acb 100644
--- a/libc/src/stdio/rename.h
+++ b/libc/src/stdio/rename.h
@@ -18,4 +18,3 @@ 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/rename_test.cpp b/libc/test/src/stdio/rename_test.cpp
index f3b15bc83772c5..e89e5153c44074 100644
--- a/libc/test/src/stdio/rename_test.cpp
+++ b/libc/test/src/stdio/rename_test.cpp
@@ -34,7 +34,8 @@ TEST(LlvmLibcRenameTest, CreateAndRenameFile) {
 
   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::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));
 }
@@ -45,6 +46,6 @@ TEST(LlvmLibcRenameTest, RenameNonExistent) {
   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));
+  ASSERT_THAT(LIBC_NAMESPACE::rename("non-existent", TEST_FILEPATH1),
+              Fails(ENOENT));
 }
-



More information about the libc-commits mailing list