From 9f7ee389c14eb49dd04f98646a3e04f30982d3f2 Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 07:48:04 +0000 Subject: [PATCH 1/7] [libc] fchown initial impl --- libc/config/linux/x86_64/entrypoints.txt | 1 + libc/include/unistd.yaml | 8 ++++ libc/src/unistd/CMakeLists.txt | 7 ++++ libc/src/unistd/fchown.h | 23 +++++++++++ libc/src/unistd/linux/CMakeLists.txt | 14 +++++++ libc/src/unistd/linux/fchown.cpp | 29 ++++++++++++++ libc/test/src/unistd/CMakeLists.txt | 20 ++++++++++ libc/test/src/unistd/fchown_test.cpp | 51 ++++++++++++++++++++++++ 8 files changed, 153 insertions(+) create mode 100644 libc/src/unistd/fchown.h create mode 100644 libc/src/unistd/linux/fchown.cpp create mode 100644 libc/test/src/unistd/fchown_test.cpp diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index a44e2041e57f2..f4012514fe20e 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -334,6 +334,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.execve libc.src.unistd.faccessat libc.src.unistd.fchdir + libc.src.unistd.fchown libc.src.unistd.fpathconf libc.src.unistd.fsync libc.src.unistd.ftruncate diff --git a/libc/include/unistd.yaml b/libc/include/unistd.yaml index 0e5b22e627b67..3f5e957768533 100644 --- a/libc/include/unistd.yaml +++ b/libc/include/unistd.yaml @@ -120,6 +120,14 @@ functions: return_type: int arguments: - type: int + - name: fchown + standards: + - POSIX + return_type: int + arguments: + - type: int + - type: uid_t + - type: gid_t - name: fork standards: - POSIX diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt index 337480cbbf928..b7444a4722b0d 100644 --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -76,6 +76,13 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.fchdir ) +add_entrypoint_object( + fchown + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.fchown +) + add_entrypoint_object( fork ALIAS diff --git a/libc/src/unistd/fchown.h b/libc/src/unistd/fchown.h new file mode 100644 index 0000000000000..23c6295da1a43 --- /dev/null +++ b/libc/src/unistd/fchown.h @@ -0,0 +1,23 @@ +//===-- Implementation header for fchown ------------------------*- 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_UNISTD_FCHOWN_H_ +#define LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ + +#include "hdr/types/gid_t.h" +#include "hdr/types/uid_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int fchown(int fildes, uid_t owner, gid_t group); + +} // namespace LIBC_NAMESPACE_DECL + + +#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt index c2dacc6456e27..c45b6ef1c5d80 100644 --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -120,6 +120,20 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + fchown + SRCS + fchown.cpp + HDRS + ../fchown.h + DEPENDS + libc.hdr.types.uid_t + libc.hdr.types.gid_t + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + add_entrypoint_object( fork SRCS diff --git a/libc/src/unistd/linux/fchown.cpp b/libc/src/unistd/linux/fchown.cpp new file mode 100644 index 0000000000000..63cad81ea585b --- /dev/null +++ b/libc/src/unistd/linux/fchown.cpp @@ -0,0 +1,29 @@ +//===-- Linux implementation of fchown ------------------------------------===// +// +// 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/unistd/fchown.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" + +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, fchown, (int fildes, uid_t owner, gid_t group)) { + int ret = LIBC_NAMESPACE::syscall_impl(SYS_fchown, fildes, owner, group); + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt index 07070535459ec..3012ea9a466f4 100644 --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -146,6 +146,26 @@ add_libc_unittest( libc.test.UnitTest.ErrnoSetterMatcher ) +add_libc_unittest( + fchown_test + SUITE + libc_unistd_unittests + SRCS + fchown_test.cpp + DEPENDS + libc.hdr.fcntl_macros + libc.include.unistd + libc.src.errno.errno + libc.src.unistd.fchown + libc.src.unistd.close + libc.src.unistd.unlink + libc.src.fcntl.open + libc.src.unistd.getuid + libc.src.unistd.getgid + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher +) + add_libc_unittest( ftruncate_test SUITE diff --git a/libc/test/src/unistd/fchown_test.cpp b/libc/test/src/unistd/fchown_test.cpp new file mode 100644 index 0000000000000..b44b728d3889e --- /dev/null +++ b/libc/test/src/unistd/fchown_test.cpp @@ -0,0 +1,51 @@ +//===-- Unittests for fchown ----------------------------------------------===// +// +// 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/unistd/fchown.h" +#include "src/unistd/close.h" +#include "src/unistd/getgid.h" +#include "src/unistd/getuid.h" +#include "src/unistd/unlink.h" + +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" +#include "test/UnitTest/Test.h" + +#include "hdr/fcntl_macros.h" +#include + +using LlvmLibcFchownTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcFchownTest, FchownSuccess) { + using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; + uid_t my_uid = LIBC_NAMESPACE::getuid(); + gid_t my_gid = LIBC_NAMESPACE::getgid(); + constexpr const char *FILENAME = "fchown.test"; + auto TEST_FILE = libc_make_test_file_path(FILENAME); + + // Create a test file. + int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU); + ASSERT_ERRNO_SUCCESS(); + ASSERT_GT(write_fd, 0); + + // Change the ownership of the file. + ASSERT_THAT(LIBC_NAMESPACE::fchown(write_fd, my_uid, my_gid), Succeeds(0)); + + // Close the file descriptor. + ASSERT_THAT(LIBC_NAMESPACE::close(write_fd), Succeeds(0)); + + // Clean up the test file. + ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0)); +} + +TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) { + using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; + ASSERT_THAT(LIBC_NAMESPACE::chown(-1, 1000, 1000), + Fails(ENOENT)); +} From 74e5658f7efc21e0e25ceb4fad4316b551086112 Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 07:50:05 +0000 Subject: [PATCH 2/7] clang-format --- libc/src/unistd/fchown.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libc/src/unistd/fchown.h b/libc/src/unistd/fchown.h index 23c6295da1a43..575f6173e980f 100644 --- a/libc/src/unistd/fchown.h +++ b/libc/src/unistd/fchown.h @@ -19,5 +19,4 @@ int fchown(int fildes, uid_t owner, gid_t group); } // namespace LIBC_NAMESPACE_DECL - -#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ +#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ From e9af916bd7e020ddec16cfe67cfbd3973d6a51ad Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 07:55:03 +0000 Subject: [PATCH 3/7] clang-format on test_fchown.cpp --- libc/test/src/unistd/fchown_test.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libc/test/src/unistd/fchown_test.cpp b/libc/test/src/unistd/fchown_test.cpp index b44b728d3889e..c29914ef4e4fc 100644 --- a/libc/test/src/unistd/fchown_test.cpp +++ b/libc/test/src/unistd/fchown_test.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/fcntl/open.h" -#include "src/unistd/fchown.h" #include "src/unistd/close.h" +#include "src/unistd/fchown.h" #include "src/unistd/getgid.h" #include "src/unistd/getuid.h" #include "src/unistd/unlink.h" @@ -46,6 +46,5 @@ TEST_F(LlvmLibcFchownTest, FchownSuccess) { TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; - ASSERT_THAT(LIBC_NAMESPACE::chown(-1, 1000, 1000), - Fails(ENOENT)); + ASSERT_THAT(LIBC_NAMESPACE::chown(-1, 1000, 1000), Fails(ENOENT)); } From 2b614b4d8bc2e3effe350217fd1f175c0543ae4f Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 16:45:50 +0000 Subject: [PATCH 4/7] Fix fchown failure test --- libc/test/src/unistd/fchown_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/test/src/unistd/fchown_test.cpp b/libc/test/src/unistd/fchown_test.cpp index c29914ef4e4fc..cd3b6b85319e0 100644 --- a/libc/test/src/unistd/fchown_test.cpp +++ b/libc/test/src/unistd/fchown_test.cpp @@ -46,5 +46,5 @@ TEST_F(LlvmLibcFchownTest, FchownSuccess) { TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; - ASSERT_THAT(LIBC_NAMESPACE::chown(-1, 1000, 1000), Fails(ENOENT)); + ASSERT_THAT(LIBC_NAMESPACE::fchown(-1, 1000, 1000), Fails(ENOENT)); } From fd262a7b6d74a4f235157adae3fc8ad60a5fdaa9 Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 23:06:29 +0000 Subject: [PATCH 5/7] Update error code in fchown failure test --- libc/test/src/unistd/fchown_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/test/src/unistd/fchown_test.cpp b/libc/test/src/unistd/fchown_test.cpp index cd3b6b85319e0..868814e503be6 100644 --- a/libc/test/src/unistd/fchown_test.cpp +++ b/libc/test/src/unistd/fchown_test.cpp @@ -46,5 +46,5 @@ TEST_F(LlvmLibcFchownTest, FchownSuccess) { TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; - ASSERT_THAT(LIBC_NAMESPACE::fchown(-1, 1000, 1000), Fails(ENOENT)); + ASSERT_THAT(LIBC_NAMESPACE::fchown(-1, 1000, 1000), Fails(EBADF)); } From 3476780786d8a3f613fa659f8d47d8f8481b7cd5 Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Mon, 10 Nov 2025 23:39:55 +0000 Subject: [PATCH 6/7] add fchown to aarch64 entrypoints --- libc/config/linux/aarch64/entrypoints.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index e0dd15b803253..144237aee7f93 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -327,6 +327,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.execve libc.src.unistd.faccessat libc.src.unistd.fchdir + libc.src.unistd.fchown libc.src.unistd.fpathconf libc.src.unistd.fsync libc.src.unistd.ftruncate From 63492b150f704e5bcf5f52daa7e3ac4f37299f46 Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Tue, 11 Nov 2025 00:19:17 +0000 Subject: [PATCH 7/7] Addressed review comments --- libc/src/unistd/fchown.h | 6 +++--- libc/src/unistd/linux/fchown.cpp | 2 ++ libc/test/src/unistd/fchown_test.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libc/src/unistd/fchown.h b/libc/src/unistd/fchown.h index 575f6173e980f..9ea44426568cc 100644 --- a/libc/src/unistd/fchown.h +++ b/libc/src/unistd/fchown.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ -#define LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ +#ifndef LLVM_LIBC_SRC_UNISTD_FCHOWN_H +#define LLVM_LIBC_SRC_UNISTD_FCHOWN_H #include "hdr/types/gid_t.h" #include "hdr/types/uid_t.h" @@ -19,4 +19,4 @@ int fchown(int fildes, uid_t owner, gid_t group); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H_ +#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H diff --git a/libc/src/unistd/linux/fchown.cpp b/libc/src/unistd/linux/fchown.cpp index 63cad81ea585b..9cf3d139050c1 100644 --- a/libc/src/unistd/linux/fchown.cpp +++ b/libc/src/unistd/linux/fchown.cpp @@ -11,6 +11,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "hdr/types/gid_t.h" +#include "hdr/types/uid_t.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" #include // For syscall numbers. diff --git a/libc/test/src/unistd/fchown_test.cpp b/libc/test/src/unistd/fchown_test.cpp index 868814e503be6..7954410afb929 100644 --- a/libc/test/src/unistd/fchown_test.cpp +++ b/libc/test/src/unistd/fchown_test.cpp @@ -44,7 +44,7 @@ TEST_F(LlvmLibcFchownTest, FchownSuccess) { ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0)); } -TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) { +TEST_F(LlvmLibcFchownTest, FchownInvalidFileDescriptor) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; ASSERT_THAT(LIBC_NAMESPACE::fchown(-1, 1000, 1000), Fails(EBADF)); }