[libc-commits] [libc] [libc] Implement fchown (PR #167286)

Anshul Nigham via libc-commits libc-commits at lists.llvm.org
Sun Nov 9 23:51:13 PST 2025


https://github.com/nigham updated https://github.com/llvm/llvm-project/pull/167286

>From 9f7ee389c14eb49dd04f98646a3e04f30982d3f2 Mon Sep 17 00:00:00 2001
From: Anshul Nigham <nigham at google.com>
Date: Mon, 10 Nov 2025 07:48:04 +0000
Subject: [PATCH 1/2] [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 <sys/syscall.h> // 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<int>(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 <sys/stat.h>
+
+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 <nigham at google.com>
Date: Mon, 10 Nov 2025 07:50:05 +0000
Subject: [PATCH 2/2] 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_



More information about the libc-commits mailing list