Skip to content

Commit c04807c

Browse files
authored
[libc][c11] Add stdio.h's rename() function (#85068)
Adds stdio.h's rename() function as defined in n3096. Fixes #84980.
1 parent 7678e6e commit c04807c

File tree

12 files changed

+147
-1
lines changed

12 files changed

+147
-1
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ set(TARGET_LIBC_ENTRYPOINTS
195195

196196
# stdio.h entrypoints
197197
libc.src.stdio.remove
198+
libc.src.stdio.rename
198199
libc.src.stdio.sprintf
199200
libc.src.stdio.snprintf
200201
libc.src.stdio.vsprintf

libc/config/linux/riscv/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ set(TARGET_LIBC_ENTRYPOINTS
196196

197197
# stdio.h entrypoints
198198
libc.src.stdio.remove
199+
libc.src.stdio.rename
199200
libc.src.stdio.sprintf
200201
libc.src.stdio.snprintf
201202
libc.src.stdio.fprintf

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ set(TARGET_LIBC_ENTRYPOINTS
198198

199199
# stdio.h entrypoints
200200
libc.src.stdio.remove
201+
libc.src.stdio.rename
201202
libc.src.stdio.sprintf
202203
libc.src.stdio.snprintf
203204
libc.src.stdio.fprintf

libc/docs/stdio.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ These functions operate on files on the host's system, without using the
6868
Function_Name Available
6969
============= =========
7070
remove |check|
71-
rename
71+
rename |check|
7272
tmpnam
7373
============= =========
7474

libc/spec/stdc.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,11 @@ def StdC : StandardSpec<"stdc"> {
706706
RetValSpec<IntType>,
707707
[ArgSpec<ConstCharPtr>]
708708
>,
709+
FunctionSpec<
710+
"rename",
711+
RetValSpec<IntType>,
712+
[ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>]
713+
>,
709714
FunctionSpec<
710715
"setbuf",
711716
RetValSpec<VoidType>,

libc/src/stdio/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,13 @@ add_entrypoint_object(
256256
.${LIBC_TARGET_OS}.remove
257257
)
258258

259+
add_entrypoint_object(
260+
rename
261+
ALIAS
262+
DEPENDS
263+
.${LIBC_TARGET_OS}.rename
264+
)
265+
259266
# These entrypoints have multiple potential implementations.
260267
add_stdio_entrypoint_object(feof)
261268
add_stdio_entrypoint_object(feof_unlocked)

libc/src/stdio/linux/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ add_entrypoint_object(
1212
libc.src.__support.OSUtil.osutil
1313
libc.src.errno.errno
1414
)
15+
16+
add_entrypoint_object(
17+
rename
18+
SRCS
19+
rename.cpp
20+
HDRS
21+
../rename.h
22+
DEPENDS
23+
libc.include.sys_syscall
24+
libc.src.__support.OSUtil.osutil
25+
libc.src.errno.errno
26+
)

libc/src/stdio/linux/rename.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Linux implementation of rename ------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/rename.h"
10+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
11+
#include "src/__support/common.h"
12+
#include "src/errno/libc_errno.h"
13+
#include <sys/syscall.h> // For syscall numbers.
14+
15+
namespace LIBC_NAMESPACE {
16+
17+
LLVM_LIBC_FUNCTION(int, rename, (const char *oldpath, const char *newpath)) {
18+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_rename, oldpath, newpath);
19+
20+
if (ret >= 0)
21+
return 0;
22+
libc_errno = -ret;
23+
return -1;
24+
}
25+
26+
} // namespace LIBC_NAMESPACE

libc/src/stdio/rename.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation header of rename -------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STDIO_RENAME_H
10+
#define LLVM_LIBC_SRC_STDIO_RENAME_H
11+
12+
namespace LIBC_NAMESPACE {
13+
14+
int rename(const char *oldpath, const char *newpath);
15+
16+
} // namespace LIBC_NAMESPACE
17+
18+
#endif // LLVM_LIBC_SRC_STDIO_RENAME_H

libc/test/src/stdio/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,21 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
354354
libc.src.unistd.access
355355
libc.src.unistd.close
356356
)
357+
358+
add_libc_test(
359+
rename_test
360+
SUITE
361+
libc_stdio_unittests
362+
SRCS
363+
rename_test.cpp
364+
DEPENDS
365+
libc.src.errno.errno
366+
libc.src.fcntl.open
367+
libc.src.stdio.rename
368+
libc.src.unistd.access
369+
libc.src.unistd.close
370+
libc.test.UnitTest.ErrnoSetterMatcher
371+
)
357372
endif()
358373

359374
add_libc_test(

libc/test/src/stdio/rename_test.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===-- Unittests for rename ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/errno/libc_errno.h"
10+
#include "src/fcntl/open.h"
11+
#include "src/stdio/rename.h"
12+
#include "src/unistd/access.h"
13+
#include "src/unistd/close.h"
14+
#include "test/UnitTest/ErrnoSetterMatcher.h"
15+
#include "test/UnitTest/Test.h"
16+
17+
TEST(LlvmLibcRenameTest, CreateAndRenameFile) {
18+
// The test strategy is to create a file and rename it, and also verify that
19+
// it was renamed.
20+
LIBC_NAMESPACE::libc_errno = 0;
21+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
22+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
23+
24+
constexpr const char *FILENAME0 = "rename.test.file0";
25+
auto TEST_FILEPATH0 = libc_make_test_file_path(FILENAME0);
26+
27+
int fd = LIBC_NAMESPACE::open(TEST_FILEPATH0, O_WRONLY | O_CREAT, S_IRWXU);
28+
ASSERT_ERRNO_SUCCESS();
29+
ASSERT_GT(fd, 0);
30+
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
31+
ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Succeeds(0));
32+
33+
constexpr const char *FILENAME1 = "rename.test.file1";
34+
auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
35+
ASSERT_THAT(LIBC_NAMESPACE::rename(TEST_FILEPATH0, TEST_FILEPATH1),
36+
Succeeds(0));
37+
ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH1, F_OK), Succeeds(0));
38+
ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Fails(ENOENT));
39+
}
40+
41+
TEST(LlvmLibcRenameTest, RenameNonExistent) {
42+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
43+
44+
constexpr const char *FILENAME1 = "rename.test.file1";
45+
auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
46+
47+
ASSERT_THAT(LIBC_NAMESPACE::rename("non-existent", TEST_FILEPATH1),
48+
Fails(ENOENT));
49+
}

utils/bazel/llvm-project-overlay/libc/BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,6 +3262,17 @@ libc_function(
32623262
],
32633263
)
32643264

3265+
libc_function(
3266+
name = "rename",
3267+
srcs = ["src/stdio/linux/rename.cpp"],
3268+
hdrs = ["src/stdio/rename.h"],
3269+
deps = [
3270+
":__support_common",
3271+
":__support_osutil_syscall",
3272+
":errno",
3273+
],
3274+
)
3275+
32653276
############################### sys/stat targets ###############################
32663277

32673278
libc_function(

0 commit comments

Comments
 (0)