[libc-commits] [libc] [libc] implement pathconf/fpathconf (PR #87165)

Nhat Nguyen via libc-commits libc-commits at lists.llvm.org
Sun Jun 16 13:20:01 PDT 2024


https://github.com/changkhothuychung updated https://github.com/llvm/llvm-project/pull/87165

>From f428a360c32273516999042bb18416fa1a1db35a Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 30 Mar 2024 14:10:47 -0400
Subject: [PATCH 01/16] intiial attempt

---
 libc/config/linux/aarch64/entrypoints.txt |  2 +
 libc/config/linux/riscv/entrypoints.txt   |  2 +
 libc/config/linux/x86_64/entrypoints.txt  |  2 +
 libc/src/unistd/CMakeLists.txt            | 14 +++++
 libc/src/unistd/linux/CMakeLists.txt      | 26 +++++++++
 libc/src/unistd/linux/pathconf.cpp        | 68 +++++++++++++++++++++++
 libc/src/unistd/pathconf.h                | 20 +++++++
 7 files changed, 134 insertions(+)
 create mode 100644 libc/src/unistd/linux/pathconf.cpp
 create mode 100644 libc/src/unistd/pathconf.h

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 78da7f0b334b1..be0c4bebfd95a 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -282,6 +282,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.dup3
     libc.src.unistd.execve
     libc.src.unistd.fchdir
+    libc.src.unistd.fpathconf
     libc.src.unistd.fsync
     libc.src.unistd.ftruncate
     libc.src.unistd.getcwd
@@ -293,6 +294,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.link
     libc.src.unistd.linkat
     libc.src.unistd.lseek
+    libc.src.unistd.pathconf
     libc.src.unistd.pread
     libc.src.unistd.pwrite
     libc.src.unistd.read
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 5aae4e246cfb3..2d8f9b1f6dd82 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -287,6 +287,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.dup3
     libc.src.unistd.execve
     libc.src.unistd.fchdir
+    libc.src.unistd.fpathconf
     libc.src.unistd.fsync
     libc.src.unistd.ftruncate
     libc.src.unistd.getcwd
@@ -298,6 +299,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.link
     libc.src.unistd.linkat
     libc.src.unistd.lseek
+    libc.src.unistd.pathconf
     libc.src.unistd.pread
     libc.src.unistd.pwrite
     libc.src.unistd.read
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5b428e51aee62..0f00f264ea149 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -297,6 +297,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.dup3
     libc.src.unistd.execve
     libc.src.unistd.fchdir
+    libc.src.unistd.fpathconf
     libc.src.unistd.fsync
     libc.src.unistd.ftruncate
     libc.src.unistd.getcwd
@@ -308,6 +309,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.link
     libc.src.unistd.linkat
     libc.src.unistd.lseek
+    libc.src.unistd.pathconf
     libc.src.unistd.pread
     libc.src.unistd.pwrite
     libc.src.unistd.read
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index e22b0e1872caa..20c87f668b381 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -58,6 +58,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fork
 )
 
+add_entrypoint_object(
+  fpathconf
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.fpathconf
+)
+
 add_entrypoint_object(
   execv
   ALIAS
@@ -149,6 +156,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.lseek
 )
 
+add_entrypoint_object(
+  pathconf
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.pathconf
+)
+
 add_entrypoint_object(
   pread
   ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index df85d44e9e9ed..0ee59d5391ac5 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -105,6 +105,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  fpathconf
+  SRCS
+    fpathconf.cpp
+  HDRS
+    ../fpathconf.h
+  DEPENDS
+    libc.include.unistd
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   execv
   SRCS
@@ -273,6 +286,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  pathconf
+  SRCS
+  pathconf.cpp
+  HDRS
+    ../pathconf.h
+  DEPENDS
+    libc.include.unistd
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   pread
   SRCS
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
new file mode 100644
index 0000000000000..fed94e7d42371
--- /dev/null
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -0,0 +1,68 @@
+//===-- Linux implementation of pathconf ----------------------------------===//
+//
+// 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/pread.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
+#include "src/errno/libc_errno.h"
+#include <stdint.h> // For uint64_t.
+#include <sys/statvfs.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+static long pathconfig(const struct statvfs &s, int name) {
+  switch (name) {
+  case _PC_LINK_MAX:
+    return _POSIX_LINK_MAX;
+
+  case _PC_MAX_CANON:
+    return _POSIX_MAX_CANON;
+
+  case _PC_MAX_INPUT:
+    return _POSIX_MAX_INPUT;
+
+  case _PC_NAME_MAX:
+    return _POSIX_NAME_MAX;
+
+  case _PC_PATH_MAX:
+    return _POSIX_PATH_MAX;
+
+  case _PC_PIPE_BUF:
+    return _POSIX_PIPE_BUF;
+
+  case _PC_CHOWN_RESTRICTED:
+    return _POSIX_CHOWN_RESTRICTED;
+
+  case _PC_NO_TRUNC:
+    return _POSIX_NO_TRUNC;
+
+  case _PC_VDISABLE:
+    return _POSIX_VDISABLE;
+  }
+}
+
+LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
+  struct statvfs sb;
+  if (statvfs(path, &sb) == -1) {
+    return -1;
+  }
+  return pathconfig(sb, name);
+}
+
+LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
+  struct statvfs sb;
+  if (statvfs(path, &sb) == -1) {
+    return -1;
+  }
+  return pathconfig(sb, name);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/pathconf.h b/libc/src/unistd/pathconf.h
new file mode 100644
index 0000000000000..a397cd9323bbb
--- /dev/null
+++ b/libc/src/unistd/pathconf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pathconf ----------------------*- 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_PREAD_H
+#define LLVM_LIBC_SRC_UNISTD_PREAD_H
+
+#include <unistd.h>
+
+namespace LIBC_NAMESPACE {
+
+long pathconf(char *path, int name);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_UNISTD_PREAD_H

>From 480690f84a39ac8dbeb06402928decf792a46f36 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 30 Mar 2024 14:22:00 -0400
Subject: [PATCH 02/16] remove fpathconf

---
 libc/src/unistd/CMakeLists.txt       |  7 -------
 libc/src/unistd/linux/CMakeLists.txt | 13 -------------
 2 files changed, 20 deletions(-)

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 20c87f668b381..9e81d5904447d 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -58,13 +58,6 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fork
 )
 
-add_entrypoint_object(
-  fpathconf
-  ALIAS
-  DEPENDS
-    .${LIBC_TARGET_OS}.fpathconf
-)
-
 add_entrypoint_object(
   execv
   ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 0ee59d5391ac5..dfea71ed3d3dc 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -105,19 +105,6 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
-add_entrypoint_object(
-  fpathconf
-  SRCS
-    fpathconf.cpp
-  HDRS
-    ../fpathconf.h
-  DEPENDS
-    libc.include.unistd
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
-    libc.src.errno.errno
-)
-
 add_entrypoint_object(
   execv
   SRCS

>From c585630cab9f7e1d4ed80b36a4f6b57a8af6a7cf Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 30 Mar 2024 14:31:36 -0400
Subject: [PATCH 03/16] add fpathconf

---
 libc/src/unistd/CMakeLists.txt       |  7 ++++
 libc/src/unistd/fpathconf.h          | 18 +++++++++
 libc/src/unistd/linux/CMakeLists.txt | 13 ++++++
 libc/src/unistd/linux/fpathconf.cpp  | 60 ++++++++++++++++++++++++++++
 libc/src/unistd/linux/pathconf.cpp   |  8 ----
 5 files changed, 98 insertions(+), 8 deletions(-)
 create mode 100644 libc/src/unistd/fpathconf.h
 create mode 100644 libc/src/unistd/linux/fpathconf.cpp

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 9e81d5904447d..20c87f668b381 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -58,6 +58,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fork
 )
 
+add_entrypoint_object(
+  fpathconf
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.fpathconf
+)
+
 add_entrypoint_object(
   execv
   ALIAS
diff --git a/libc/src/unistd/fpathconf.h b/libc/src/unistd/fpathconf.h
new file mode 100644
index 0000000000000..d80d94ca3c2ed
--- /dev/null
+++ b/libc/src/unistd/fpathconf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fpathconf ---------------------*- 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_FSYNC_H
+#define LLVM_LIBC_SRC_UNISTD_FSYNC_H
+
+namespace LIBC_NAMESPACE {
+
+long fpathconf(int fd, int name);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_UNISTD_FSYNC_H
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index dfea71ed3d3dc..0ee59d5391ac5 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -105,6 +105,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  fpathconf
+  SRCS
+    fpathconf.cpp
+  HDRS
+    ../fpathconf.h
+  DEPENDS
+    libc.include.unistd
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   execv
   SRCS
diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
new file mode 100644
index 0000000000000..16bb0b6334e2c
--- /dev/null
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -0,0 +1,60 @@
+//===-- Linux implementation of fpathconf ---------------------------------===//
+//
+// 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/fsync.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 {
+
+static long pathconfig(const struct statvfs &s, int name) {
+  switch (name) {
+  case _PC_LINK_MAX:
+    return _POSIX_LINK_MAX;
+
+  case _PC_MAX_CANON:
+    return _POSIX_MAX_CANON;
+
+  case _PC_MAX_INPUT:
+    return _POSIX_MAX_INPUT;
+
+  case _PC_NAME_MAX:
+    return _POSIX_NAME_MAX;
+
+  case _PC_PATH_MAX:
+    return _POSIX_PATH_MAX;
+
+  case _PC_PIPE_BUF:
+    return _POSIX_PIPE_BUF;
+
+  case _PC_CHOWN_RESTRICTED:
+    return _POSIX_CHOWN_RESTRICTED;
+
+  case _PC_NO_TRUNC:
+    return _POSIX_NO_TRUNC;
+
+  case _PC_VDISABLE:
+    return _POSIX_VDISABLE;
+  }
+}
+
+LLVM_LIBC_FUNCTION(int, fsync, (int fd)) {
+  LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
+    struct statvfs sb;
+    if (statvfs(path, &sb) == -1) {
+      return -1;
+    }
+    return pathconfig(sb, name);
+  }
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index fed94e7d42371..b1ecc4c80c3d4 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -57,12 +57,4 @@ LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
   return pathconfig(sb, name);
 }
 
-LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
-  struct statvfs sb;
-  if (statvfs(path, &sb) == -1) {
-    return -1;
-  }
-  return pathconfig(sb, name);
-}
-
 } // namespace LIBC_NAMESPACE

>From b9436a33b4545f19f4043be4ebb71c855d51f104 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 30 Mar 2024 14:43:13 -0400
Subject: [PATCH 04/16] fstatvfs

---
 libc/src/unistd/linux/pathconf.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index b1ecc4c80c3d4..a4ffb11a5acce 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -13,7 +13,7 @@
 #include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
 #include "src/errno/libc_errno.h"
 #include <stdint.h> // For uint64_t.
-#include <sys/statvfs.h>
+#include <sys/fstatvfs.h>
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE {
@@ -51,7 +51,7 @@ static long pathconfig(const struct statvfs &s, int name) {
 
 LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
   struct statvfs sb;
-  if (statvfs(path, &sb) == -1) {
+  if (fstatvfs(path, &sb) == -1) {
     return -1;
   }
   return pathconfig(sb, name);

>From 001e9a25308b3f82e80c2c0027763c5177160cb8 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sun, 5 May 2024 12:51:25 -0400
Subject: [PATCH 05/16] some fix

---
 libc/src/unistd/linux/fpathconf.cpp | 14 +++++---------
 libc/src/unistd/linux/pathconf.cpp  | 16 ++++++++++------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
index 16bb0b6334e2c..f3909c857762c 100644
--- a/libc/src/unistd/linux/fpathconf.cpp
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/unistd/fsync.h"
-
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 
@@ -47,14 +45,12 @@ static long pathconfig(const struct statvfs &s, int name) {
   }
 }
 
-LLVM_LIBC_FUNCTION(int, fsync, (int fd)) {
-  LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
-    struct statvfs sb;
-    if (statvfs(path, &sb) == -1) {
-      return -1;
-    }
-    return pathconfig(sb, name);
+LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
+  struct statvfs sb;
+  if (statvfs(path, &sb) == -1) {
+    return -1;
   }
+  return pathconfig(sb, name);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index a4ffb11a5acce..a79a4dcd781f9 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -18,10 +18,10 @@
 
 namespace LIBC_NAMESPACE {
 
-static long pathconfig(const struct statvfs &s, int name) {
+static long pathconfig(const struct statfs &s, int name) {
   switch (name) {
   case _PC_LINK_MAX:
-    return _POSIX_LINK_MAX;
+    return s.f_type;
 
   case _PC_MAX_CANON:
     return _POSIX_MAX_CANON;
@@ -30,7 +30,7 @@ static long pathconfig(const struct statvfs &s, int name) {
     return _POSIX_MAX_INPUT;
 
   case _PC_NAME_MAX:
-    return _POSIX_NAME_MAX;
+    return s.f_namemax;
 
   case _PC_PATH_MAX:
     return _POSIX_PATH_MAX;
@@ -50,11 +50,15 @@ static long pathconfig(const struct statvfs &s, int name) {
 }
 
 LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
-  struct statvfs sb;
-  if (fstatvfs(path, &sb) == -1) {
+  // struct statfs sb;
+  // if (fstatfs(PathFD(path), &sb) == -1) {
+  //   return -1;
+  // }
+  cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);
+  if (!result.has_value()) {
     return -1;
   }
-  return pathconfig(sb, name);
+  return pathconfig(result.value(), name);
 }
 
 } // namespace LIBC_NAMESPACE

>From ff1969213ca496f1ea9cfce4aca2f31ac3e355b5 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 11 May 2024 08:55:15 -0400
Subject: [PATCH 06/16] some fix and add test

---
 libc/src/unistd/linux/fpathconf.cpp     | 74 +++++++++++++++++++++++--
 libc/src/unistd/linux/pathconf.cpp      | 67 ++++++++++++++++++++--
 libc/test/src/unistd/fpathconf_test.cpp | 25 +++++++++
 libc/test/src/unistd/pathconf_test.cpp  | 25 +++++++++
 4 files changed, 180 insertions(+), 11 deletions(-)
 create mode 100644 libc/test/src/unistd/fpathconf_test.cpp
 create mode 100644 libc/test/src/unistd/pathconf_test.cpp

diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
index f3909c857762c..d2a44ca0b8b30 100644
--- a/libc/src/unistd/linux/fpathconf.cpp
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -14,10 +14,62 @@
 
 namespace LIBC_NAMESPACE {
 
-static long pathconfig(const struct statvfs &s, int name) {
+static long filesizebits(const struct statfs &s) {
+  switch (s.f_type) {
+  case JFFS2_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case NCP_SUPER_MAGIC:
+    return 32;
+  }
+  return 64;
+}
+
+static long link_max(const struct statfs &s) {
+  switch (s.f_type) {
+  case EXT2_SUPER_MAGIC:
+    return 32000;
+  case MINIX_SUPER_MAGIC:
+    return 250;
+  case MINIX2_SUPER_MAGIC:
+    return 65530;
+  case REISERFS_SUPER_MAGIC:
+    return 0xffff - 1000;
+  case UFS_MAGIC:
+    return 32000;
+  }
+  return LINK_MAX;
+}
+
+static long _2_symlinks(const struct statfs &s) {
+  switch (s.f_type) {
+  case ADFS_SUPER_MAGIC:
+  case BFS_MAGIC:
+  case CRAMFS_MAGIC:
+  case EFS_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case QNX4_SUPER_MAGIC:
+    return 0;
+  }
+  return 1;
+}
+
+static long fpathconfig(const struct fstatfs &s, int name) {
   switch (name) {
   case _PC_LINK_MAX:
-    return _POSIX_LINK_MAX;
+    return link_max(s);
+
+  case _PC_FILESIZEBITS:
+    return filesizebits(s);
+
+  case _PC_2_SYMLINKS:
+    return _2_symlinks(s);
+
+  case _PC_REC_MIN_XFER_SIZE:
+    return s.f_bsize;
+
+  case _PC_ALLOC_SIZE_MIN:
+  case _PC_REC_XFER_ALIGN:
+    return s.f_frsize;
 
   case _PC_MAX_CANON:
     return _POSIX_MAX_CANON;
@@ -26,7 +78,7 @@ static long pathconfig(const struct statvfs &s, int name) {
     return _POSIX_MAX_INPUT;
 
   case _PC_NAME_MAX:
-    return _POSIX_NAME_MAX;
+    return s.f_namemax;
 
   case _PC_PATH_MAX:
     return _POSIX_PATH_MAX;
@@ -42,15 +94,25 @@ static long pathconfig(const struct statvfs &s, int name) {
 
   case _PC_VDISABLE:
     return _POSIX_VDISABLE;
+
+  case _PC_ASYNC_IO:
+  case _PC_PRIO_IO:
+  case _PC_REC_INCR_XFER_SIZE:
+  case _PC_REC_MAX_XFER_SIZE:
+  case _PC_SYMLINK_MAX:
+  case _PC_SYNC_IO:
+  default:
+    return -1;
   }
 }
 
 LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
-  struct statvfs sb;
-  if (statvfs(path, &sb) == -1) {
+  struct fstatfs sb;
+  cpp::optional<LinuxStatFs> result = linux_fstatfs(fd);
+  if (!result.has_value()) {
     return -1;
   }
-  return pathconfig(sb, name);
+  return fpathconfig(sb, name);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index a79a4dcd781f9..89c018855f8ce 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -18,10 +18,62 @@
 
 namespace LIBC_NAMESPACE {
 
+static long filesizebits(const struct statfs &s) {
+  switch (s.f_type) {
+  case JFFS2_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case NCP_SUPER_MAGIC:
+    return 32;
+  }
+  return 64;
+}
+
+static long link_max(const struct statfs &s) {
+  switch (s.f_type) {
+  case EXT2_SUPER_MAGIC:
+    return 32000;
+  case MINIX_SUPER_MAGIC:
+    return 250;
+  case MINIX2_SUPER_MAGIC:
+    return 65530;
+  case REISERFS_SUPER_MAGIC:
+    return 0xffff - 1000;
+  case UFS_MAGIC:
+    return 32000;
+  }
+  return LINK_MAX;
+}
+
+static long _2_symlinks(const struct statfs &s) {
+  switch (s.f_type) {
+  case ADFS_SUPER_MAGIC:
+  case BFS_MAGIC:
+  case CRAMFS_MAGIC:
+  case EFS_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case QNX4_SUPER_MAGIC:
+    return 0;
+  }
+  return 1;
+}
+
 static long pathconfig(const struct statfs &s, int name) {
   switch (name) {
   case _PC_LINK_MAX:
-    return s.f_type;
+    return link_max(s);
+
+  case _PC_FILESIZEBITS:
+    return filesizebits(s);
+
+  case _PC_2_SYMLINKS:
+    return _2_symlinks(s);
+
+  case _PC_REC_MIN_XFER_SIZE:
+    return s.f_bsize;
+
+  case _PC_ALLOC_SIZE_MIN:
+  case _PC_REC_XFER_ALIGN:
+    return s.f_frsize;
 
   case _PC_MAX_CANON:
     return _POSIX_MAX_CANON;
@@ -46,14 +98,19 @@ static long pathconfig(const struct statfs &s, int name) {
 
   case _PC_VDISABLE:
     return _POSIX_VDISABLE;
+
+  case _PC_ASYNC_IO:
+  case _PC_PRIO_IO:
+  case _PC_REC_INCR_XFER_SIZE:
+  case _PC_REC_MAX_XFER_SIZE:
+  case _PC_SYMLINK_MAX:
+  case _PC_SYNC_IO:
+  default:
+    return -1;
   }
 }
 
 LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
-  // struct statfs sb;
-  // if (fstatfs(PathFD(path), &sb) == -1) {
-  //   return -1;
-  // }
   cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);
   if (!result.has_value()) {
     return -1;
diff --git a/libc/test/src/unistd/fpathconf_test.cpp b/libc/test/src/unistd/fpathconf_test.cpp
new file mode 100644
index 0000000000000..f51115981022f
--- /dev/null
+++ b/libc/test/src/unistd/fpathconf_test.cpp
@@ -0,0 +1,25 @@
+//===-- Unittests for fpathconf
+//------------------------------------------------===//
+//
+// 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/close.h"
+#include "src/unistd/fpathconf.h"
+
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcPipeTest, SmokeTest) {
+  constexpr const char *FILENAME = "fpathconf.test";
+  auto TEST_FILE = libc_make_test_file_path(FILENAME);
+  int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_EQ(LIBC_NAMESPACE::pathconf(fd, _PC_SYNC_IO), -1);
+  ASSERT_EQ(LIBC_NAMESPACE::pathconf(fd, _PC_PATH_MAX), _POSIX_PATH_MAX);
+}
+
+// TODO: Functionality tests
diff --git a/libc/test/src/unistd/pathconf_test.cpp b/libc/test/src/unistd/pathconf_test.cpp
new file mode 100644
index 0000000000000..e8503facb9fea
--- /dev/null
+++ b/libc/test/src/unistd/pathconf_test.cpp
@@ -0,0 +1,25 @@
+//===-- Unittests for pathconf
+//------------------------------------------------===//
+//
+// 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/close.h"
+#include "src/unistd/pathconf.h"
+
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcPipeTest, SmokeTest) {
+  constexpr const char *FILENAME = "fpathconf.test";
+  auto TEST_FILE = libc_make_test_file_path(FILENAME);
+  int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_SYNC_IO), -1);
+  ASSERT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_PATH_MAX), _POSIX_PATH_MAX);
+}
+
+// TODO: Functionality tests

>From 1b83f13ce16e6a62d9b88e1d5c7c879f1c4dc6a9 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sun, 12 May 2024 23:24:38 -0400
Subject: [PATCH 07/16] some fix

---
 libc/src/unistd/linux/fpathconf.cpp | 11 ++++++-----
 libc/src/unistd/linux/pathconf.cpp  | 10 ++++++----
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
index d2a44ca0b8b30..ca9c9b0911328 100644
--- a/libc/src/unistd/linux/fpathconf.cpp
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -101,18 +101,19 @@ static long fpathconfig(const struct fstatfs &s, int name) {
   case _PC_REC_MAX_XFER_SIZE:
   case _PC_SYMLINK_MAX:
   case _PC_SYNC_IO:
+    return -1;
+
   default:
+    errno = EINVAL;
     return -1;
   }
 }
 
 LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
   struct fstatfs sb;
-  cpp::optional<LinuxStatFs> result = linux_fstatfs(fd);
-  if (!result.has_value()) {
-    return -1;
-  }
-  return fpathconfig(sb, name);
+  if (cpp::optional<LinuxStatFs> result = linux_fstatfs(fd))
+    return fpathconfig(sb, name);
+  return -1;
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index 89c018855f8ce..80156feca18ad 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -105,17 +105,19 @@ static long pathconfig(const struct statfs &s, int name) {
   case _PC_REC_MAX_XFER_SIZE:
   case _PC_SYMLINK_MAX:
   case _PC_SYNC_IO:
+    return -1;
+
   default:
+    errno = EINVAL;
     return -1;
   }
 }
 
 LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
-  cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);
-  if (!result.has_value()) {
-    return -1;
+  if (cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);) {
+    return pathconfig(result.value(), name);
   }
-  return pathconfig(result.value(), name);
+  return -1;
 }
 
 } // namespace LIBC_NAMESPACE

>From 4a6c986a68e33d477552a717a643f5e34d0a8445 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Mon, 13 May 2024 21:10:49 -0400
Subject: [PATCH 08/16] refactor

---
 libc/src/unistd/CMakeLists.txt           |   7 ++
 libc/src/unistd/linux/CMakeLists.txt     |  15 +++
 libc/src/unistd/linux/fpathconf.cpp      |  99 +-------------------
 libc/src/unistd/linux/pathconf.cpp       |  99 +-------------------
 libc/src/unistd/linux/pathconf_utils.cpp | 113 +++++++++++++++++++++++
 libc/src/unistd/pathconf_utils.h         |  24 +++++
 6 files changed, 163 insertions(+), 194 deletions(-)
 create mode 100644 libc/src/unistd/linux/pathconf_utils.cpp
 create mode 100644 libc/src/unistd/pathconf_utils.h

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index c5dcb6411e6dd..67a1f37f0da2a 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -174,6 +174,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.pathconf
 )
 
+add_entrypoint_object(
+  pathconf_utils
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.pathconf_utils
+)
+
 add_entrypoint_object(
   pipe
   ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index f7435c3ffda12..3fce8d3d2f1b3 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -116,6 +116,7 @@ add_entrypoint_object(
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
+    libc.src.unistd.pathconf_utils
 )
 
 add_entrypoint_object(
@@ -297,6 +298,20 @@ add_entrypoint_object(
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
+    libc.src.unistd.pathconf_utils
+)
+
+add_entrypoint_object(
+  pathconf_utils
+  SRCS
+  pathconf_utils.cpp
+  HDRS
+    ../pathconf_utils.h
+  DEPENDS
+    libc.include.unistd
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
index ca9c9b0911328..14a37da9e1637 100644
--- a/libc/src/unistd/linux/fpathconf.cpp
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -8,111 +8,16 @@
 
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
+#include "src/unistd/pathconf_utils.h"
 
 #include "src/errno/libc_errno.h"
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE {
 
-static long filesizebits(const struct statfs &s) {
-  switch (s.f_type) {
-  case JFFS2_SUPER_MAGIC:
-  case MSDOS_SUPER_MAGIC:
-  case NCP_SUPER_MAGIC:
-    return 32;
-  }
-  return 64;
-}
-
-static long link_max(const struct statfs &s) {
-  switch (s.f_type) {
-  case EXT2_SUPER_MAGIC:
-    return 32000;
-  case MINIX_SUPER_MAGIC:
-    return 250;
-  case MINIX2_SUPER_MAGIC:
-    return 65530;
-  case REISERFS_SUPER_MAGIC:
-    return 0xffff - 1000;
-  case UFS_MAGIC:
-    return 32000;
-  }
-  return LINK_MAX;
-}
-
-static long _2_symlinks(const struct statfs &s) {
-  switch (s.f_type) {
-  case ADFS_SUPER_MAGIC:
-  case BFS_MAGIC:
-  case CRAMFS_MAGIC:
-  case EFS_SUPER_MAGIC:
-  case MSDOS_SUPER_MAGIC:
-  case QNX4_SUPER_MAGIC:
-    return 0;
-  }
-  return 1;
-}
-
-static long fpathconfig(const struct fstatfs &s, int name) {
-  switch (name) {
-  case _PC_LINK_MAX:
-    return link_max(s);
-
-  case _PC_FILESIZEBITS:
-    return filesizebits(s);
-
-  case _PC_2_SYMLINKS:
-    return _2_symlinks(s);
-
-  case _PC_REC_MIN_XFER_SIZE:
-    return s.f_bsize;
-
-  case _PC_ALLOC_SIZE_MIN:
-  case _PC_REC_XFER_ALIGN:
-    return s.f_frsize;
-
-  case _PC_MAX_CANON:
-    return _POSIX_MAX_CANON;
-
-  case _PC_MAX_INPUT:
-    return _POSIX_MAX_INPUT;
-
-  case _PC_NAME_MAX:
-    return s.f_namemax;
-
-  case _PC_PATH_MAX:
-    return _POSIX_PATH_MAX;
-
-  case _PC_PIPE_BUF:
-    return _POSIX_PIPE_BUF;
-
-  case _PC_CHOWN_RESTRICTED:
-    return _POSIX_CHOWN_RESTRICTED;
-
-  case _PC_NO_TRUNC:
-    return _POSIX_NO_TRUNC;
-
-  case _PC_VDISABLE:
-    return _POSIX_VDISABLE;
-
-  case _PC_ASYNC_IO:
-  case _PC_PRIO_IO:
-  case _PC_REC_INCR_XFER_SIZE:
-  case _PC_REC_MAX_XFER_SIZE:
-  case _PC_SYMLINK_MAX:
-  case _PC_SYNC_IO:
-    return -1;
-
-  default:
-    errno = EINVAL;
-    return -1;
-  }
-}
-
 LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
-  struct fstatfs sb;
   if (cpp::optional<LinuxStatFs> result = linux_fstatfs(fd))
-    return fpathconfig(sb, name);
+    return pathconfig(result.value(), name);
   return -1;
 }
 
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index 80156feca18ad..e43f3b2125828 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -6,113 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/unistd/pread.h"
-
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
 #include "src/errno/libc_errno.h"
+#include "src/unistd/pathconf_utils.h"
+
 #include <stdint.h> // For uint64_t.
 #include <sys/fstatvfs.h>
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE {
 
-static long filesizebits(const struct statfs &s) {
-  switch (s.f_type) {
-  case JFFS2_SUPER_MAGIC:
-  case MSDOS_SUPER_MAGIC:
-  case NCP_SUPER_MAGIC:
-    return 32;
-  }
-  return 64;
-}
-
-static long link_max(const struct statfs &s) {
-  switch (s.f_type) {
-  case EXT2_SUPER_MAGIC:
-    return 32000;
-  case MINIX_SUPER_MAGIC:
-    return 250;
-  case MINIX2_SUPER_MAGIC:
-    return 65530;
-  case REISERFS_SUPER_MAGIC:
-    return 0xffff - 1000;
-  case UFS_MAGIC:
-    return 32000;
-  }
-  return LINK_MAX;
-}
-
-static long _2_symlinks(const struct statfs &s) {
-  switch (s.f_type) {
-  case ADFS_SUPER_MAGIC:
-  case BFS_MAGIC:
-  case CRAMFS_MAGIC:
-  case EFS_SUPER_MAGIC:
-  case MSDOS_SUPER_MAGIC:
-  case QNX4_SUPER_MAGIC:
-    return 0;
-  }
-  return 1;
-}
-
-static long pathconfig(const struct statfs &s, int name) {
-  switch (name) {
-  case _PC_LINK_MAX:
-    return link_max(s);
-
-  case _PC_FILESIZEBITS:
-    return filesizebits(s);
-
-  case _PC_2_SYMLINKS:
-    return _2_symlinks(s);
-
-  case _PC_REC_MIN_XFER_SIZE:
-    return s.f_bsize;
-
-  case _PC_ALLOC_SIZE_MIN:
-  case _PC_REC_XFER_ALIGN:
-    return s.f_frsize;
-
-  case _PC_MAX_CANON:
-    return _POSIX_MAX_CANON;
-
-  case _PC_MAX_INPUT:
-    return _POSIX_MAX_INPUT;
-
-  case _PC_NAME_MAX:
-    return s.f_namemax;
-
-  case _PC_PATH_MAX:
-    return _POSIX_PATH_MAX;
-
-  case _PC_PIPE_BUF:
-    return _POSIX_PIPE_BUF;
-
-  case _PC_CHOWN_RESTRICTED:
-    return _POSIX_CHOWN_RESTRICTED;
-
-  case _PC_NO_TRUNC:
-    return _POSIX_NO_TRUNC;
-
-  case _PC_VDISABLE:
-    return _POSIX_VDISABLE;
-
-  case _PC_ASYNC_IO:
-  case _PC_PRIO_IO:
-  case _PC_REC_INCR_XFER_SIZE:
-  case _PC_REC_MAX_XFER_SIZE:
-  case _PC_SYMLINK_MAX:
-  case _PC_SYNC_IO:
-    return -1;
-
-  default:
-    errno = EINVAL;
-    return -1;
-  }
-}
-
 LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
   if (cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);) {
     return pathconfig(result.value(), name);
diff --git a/libc/src/unistd/linux/pathconf_utils.cpp b/libc/src/unistd/linux/pathconf_utils.cpp
new file mode 100644
index 0000000000000..3a4cc0ab4446f
--- /dev/null
+++ b/libc/src/unistd/linux/pathconf_utils.cpp
@@ -0,0 +1,113 @@
+//===-- Linux implementation of pathconf_utils
+//---------------------------------===//
+//
+// 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/__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 {
+
+static long filesizebits(const struct statfs &s) {
+  switch (s.f_type) {
+  case JFFS2_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case NCP_SUPER_MAGIC:
+    return 32;
+  }
+  return 64;
+}
+
+static long link_max(const struct statfs &s) {
+  switch (s.f_type) {
+  case EXT2_SUPER_MAGIC:
+    return 32000;
+  case MINIX_SUPER_MAGIC:
+    return 250;
+  case MINIX2_SUPER_MAGIC:
+    return 65530;
+  case REISERFS_SUPER_MAGIC:
+    return 0xffff - 1000;
+  case UFS_MAGIC:
+    return 32000;
+  }
+  return LINK_MAX;
+}
+
+static long _2_symlinks(const struct statfs &s) {
+  switch (s.f_type) {
+  case ADFS_SUPER_MAGIC:
+  case BFS_MAGIC:
+  case CRAMFS_MAGIC:
+  case EFS_SUPER_MAGIC:
+  case MSDOS_SUPER_MAGIC:
+  case QNX4_SUPER_MAGIC:
+    return 0;
+  }
+  return 1;
+}
+
+static long fpathconfig(const struct fstatfs &s, int name) {
+  switch (name) {
+  case _PC_LINK_MAX:
+    return link_max(s);
+
+  case _PC_FILESIZEBITS:
+    return filesizebits(s);
+
+  case _PC_2_SYMLINKS:
+    return _2_symlinks(s);
+
+  case _PC_REC_MIN_XFER_SIZE:
+    return s.f_bsize;
+
+  case _PC_ALLOC_SIZE_MIN:
+  case _PC_REC_XFER_ALIGN:
+    return s.f_frsize;
+
+  case _PC_MAX_CANON:
+    return _POSIX_MAX_CANON;
+
+  case _PC_MAX_INPUT:
+    return _POSIX_MAX_INPUT;
+
+  case _PC_NAME_MAX:
+    return s.f_namemax;
+
+  case _PC_PATH_MAX:
+    return _POSIX_PATH_MAX;
+
+  case _PC_PIPE_BUF:
+    return _POSIX_PIPE_BUF;
+
+  case _PC_CHOWN_RESTRICTED:
+    return _POSIX_CHOWN_RESTRICTED;
+
+  case _PC_NO_TRUNC:
+    return _POSIX_NO_TRUNC;
+
+  case _PC_VDISABLE:
+    return _POSIX_VDISABLE;
+
+  case _PC_ASYNC_IO:
+  case _PC_PRIO_IO:
+  case _PC_REC_INCR_XFER_SIZE:
+  case _PC_REC_MAX_XFER_SIZE:
+  case _PC_SYMLINK_MAX:
+  case _PC_SYNC_IO:
+    return -1;
+
+  default:
+    errno = EINVAL;
+    return -1;
+  }
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/pathconf_utils.h b/libc/src/unistd/pathconf_utils.h
new file mode 100644
index 0000000000000..81bf7a14660e0
--- /dev/null
+++ b/libc/src/unistd/pathconf_utils.h
@@ -0,0 +1,24 @@
+//===-- Implementation header for pathconf_utils ----------------------*- 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_PREAD_H
+#define LLVM_LIBC_SRC_UNISTD_PREAD_H
+
+#include <unistd.h>
+
+namespace LIBC_NAMESPACE {
+
+static long filesizebits(const struct statfs &s);
+static long link_max(const struct statfs &s);
+static long _2_symlinks(const struct statfs &s);
+static long pathconfig(const struct fstatfs &s, int name);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_UNISTD_PREAD_H

>From 445bef670709153e2385fca8a77da88428468417 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 14 May 2024 21:06:05 -0400
Subject: [PATCH 09/16] some fix

---
 libc/src/unistd/CMakeLists.txt           |  2 +-
 libc/src/unistd/linux/CMakeLists.txt     |  2 +-
 libc/src/unistd/linux/pathconf_utils.cpp |  8 ++++----
 libc/src/unistd/pathconf_utils.h         | 12 ++++++------
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 67a1f37f0da2a..4c351d32e3ec9 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -174,7 +174,7 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.pathconf
 )
 
-add_entrypoint_object(
+add_header_library(
   pathconf_utils
   ALIAS
   DEPENDS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 3fce8d3d2f1b3..d3af612e09dc1 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -301,7 +301,7 @@ add_entrypoint_object(
     libc.src.unistd.pathconf_utils
 )
 
-add_entrypoint_object(
+add_header_library(
   pathconf_utils
   SRCS
   pathconf_utils.cpp
diff --git a/libc/src/unistd/linux/pathconf_utils.cpp b/libc/src/unistd/linux/pathconf_utils.cpp
index 3a4cc0ab4446f..ba3a7af2aff31 100644
--- a/libc/src/unistd/linux/pathconf_utils.cpp
+++ b/libc/src/unistd/linux/pathconf_utils.cpp
@@ -15,7 +15,7 @@
 
 namespace LIBC_NAMESPACE {
 
-static long filesizebits(const struct statfs &s) {
+long filesizebits(const struct statfs &s) {
   switch (s.f_type) {
   case JFFS2_SUPER_MAGIC:
   case MSDOS_SUPER_MAGIC:
@@ -25,7 +25,7 @@ static long filesizebits(const struct statfs &s) {
   return 64;
 }
 
-static long link_max(const struct statfs &s) {
+long link_max(const struct statfs &s) {
   switch (s.f_type) {
   case EXT2_SUPER_MAGIC:
     return 32000;
@@ -41,7 +41,7 @@ static long link_max(const struct statfs &s) {
   return LINK_MAX;
 }
 
-static long _2_symlinks(const struct statfs &s) {
+long _2_symlinks(const struct statfs &s) {
   switch (s.f_type) {
   case ADFS_SUPER_MAGIC:
   case BFS_MAGIC:
@@ -54,7 +54,7 @@ static long _2_symlinks(const struct statfs &s) {
   return 1;
 }
 
-static long fpathconfig(const struct fstatfs &s, int name) {
+long pathconfig(const struct fstatfs &s, int name) {
   switch (name) {
   case _PC_LINK_MAX:
     return link_max(s);
diff --git a/libc/src/unistd/pathconf_utils.h b/libc/src/unistd/pathconf_utils.h
index 81bf7a14660e0..c5db11ae33468 100644
--- a/libc/src/unistd/pathconf_utils.h
+++ b/libc/src/unistd/pathconf_utils.h
@@ -7,17 +7,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_UNISTD_PREAD_H
-#define LLVM_LIBC_SRC_UNISTD_PREAD_H
+#ifndef LLVM_LIBC_SRC_UNISTD_PATHCONF_UTILS_H
+#define LLVM_LIBC_SRC_UNISTD_PATHCONF_UTILS_H
 
 #include <unistd.h>
 
 namespace LIBC_NAMESPACE {
 
-static long filesizebits(const struct statfs &s);
-static long link_max(const struct statfs &s);
-static long _2_symlinks(const struct statfs &s);
-static long pathconfig(const struct fstatfs &s, int name);
+LIBC_INLINE long filesizebits(const struct statfs &s);
+LIBC_INLINE long link_max(const struct statfs &s);
+LIBC_INLINE long _2_symlinks(const struct statfs &s);
+LIBC_INLINE long pathconfig(const struct fstatfs &s, int name);
 
 } // namespace LIBC_NAMESPACE
 

>From fa71f67f4e10aeda08f09075cce693480b7a3f5b Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 14 May 2024 21:09:25 -0400
Subject: [PATCH 10/16] some fix

---
 libc/src/unistd/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 4c351d32e3ec9..67a1f37f0da2a 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -174,7 +174,7 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.pathconf
 )
 
-add_header_library(
+add_entrypoint_object(
   pathconf_utils
   ALIAS
   DEPENDS

>From 751e22cc0a277cd3f3c9c331f69ac441f8763fde Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Thu, 16 May 2024 23:26:58 -0400
Subject: [PATCH 11/16] some changes

---
 libc/src/unistd/CMakeLists.txt   | 2 +-
 libc/src/unistd/pathconf_utils.h | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 67a1f37f0da2a..c27b4bc8d68ac 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -174,7 +174,7 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.pathconf
 )
 
-add_entrypoint_object(
+add_object_library(
   pathconf_utils
   ALIAS
   DEPENDS
diff --git a/libc/src/unistd/pathconf_utils.h b/libc/src/unistd/pathconf_utils.h
index c5db11ae33468..f0ddbaaba5897 100644
--- a/libc/src/unistd/pathconf_utils.h
+++ b/libc/src/unistd/pathconf_utils.h
@@ -1,5 +1,4 @@
-//===-- Implementation header for pathconf_utils ----------------------*- C++
-//-*-===//
+//===-- Implementation header for pathconf_utils ----------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 2d66e8750143ec8d63afd618514e33cf85410c44 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 21 May 2024 23:37:55 -0400
Subject: [PATCH 12/16] some fix

---
 libc/src/unistd/CMakeLists.txt           | 6 ------
 libc/src/unistd/linux/CMakeLists.txt     | 6 +++---
 libc/src/unistd/linux/pathconf.cpp       | 3 ---
 libc/src/unistd/linux/pathconf_utils.cpp | 3 +--
 libc/src/unistd/pathconf_utils.h         | 8 ++++----
 libc/test/src/unistd/pathconf_test.cpp   | 3 +--
 6 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index c27b4bc8d68ac..ddafcd7c92f21 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -174,12 +174,6 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.pathconf
 )
 
-add_object_library(
-  pathconf_utils
-  ALIAS
-  DEPENDS
-    .${LIBC_TARGET_OS}.pathconf_utils
-)
 
 add_entrypoint_object(
   pipe
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index d3af612e09dc1..8b06498b0dd7d 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -290,7 +290,7 @@ add_entrypoint_object(
 add_entrypoint_object(
   pathconf
   SRCS
-  pathconf.cpp
+    pathconf.cpp
   HDRS
     ../pathconf.h
   DEPENDS
@@ -301,10 +301,10 @@ add_entrypoint_object(
     libc.src.unistd.pathconf_utils
 )
 
-add_header_library(
+add_object_library(
   pathconf_utils
   SRCS
-  pathconf_utils.cpp
+    pathconf_utils.cpp
   HDRS
     ../pathconf_utils.h
   DEPENDS
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index e43f3b2125828..cb4457b7d29d7 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -6,9 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-#include "src/__support/common.h"
-#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
 #include "src/errno/libc_errno.h"
 #include "src/unistd/pathconf_utils.h"
 
diff --git a/libc/src/unistd/linux/pathconf_utils.cpp b/libc/src/unistd/linux/pathconf_utils.cpp
index ba3a7af2aff31..7849230555aeb 100644
--- a/libc/src/unistd/linux/pathconf_utils.cpp
+++ b/libc/src/unistd/linux/pathconf_utils.cpp
@@ -1,5 +1,4 @@
-//===-- Linux implementation of pathconf_utils
-//---------------------------------===//
+//===-- Linux implementation of pathconf_utils ----------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/unistd/pathconf_utils.h b/libc/src/unistd/pathconf_utils.h
index f0ddbaaba5897..468f3f94e1844 100644
--- a/libc/src/unistd/pathconf_utils.h
+++ b/libc/src/unistd/pathconf_utils.h
@@ -13,10 +13,10 @@
 
 namespace LIBC_NAMESPACE {
 
-LIBC_INLINE long filesizebits(const struct statfs &s);
-LIBC_INLINE long link_max(const struct statfs &s);
-LIBC_INLINE long _2_symlinks(const struct statfs &s);
-LIBC_INLINE long pathconfig(const struct fstatfs &s, int name);
+long filesizebits(const struct statfs &s);
+long link_max(const struct statfs &s);
+long _2_symlinks(const struct statfs &s);
+long pathconfig(const struct fstatfs &s, int name);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/test/src/unistd/pathconf_test.cpp b/libc/test/src/unistd/pathconf_test.cpp
index e8503facb9fea..178c683a36454 100644
--- a/libc/test/src/unistd/pathconf_test.cpp
+++ b/libc/test/src/unistd/pathconf_test.cpp
@@ -1,5 +1,4 @@
-//===-- Unittests for pathconf
-//------------------------------------------------===//
+//===-- Unittests for pathconf --------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 94349c2b80f92e29f40b65f27eec7178c4666985 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 11 Jun 2024 01:00:07 -0400
Subject: [PATCH 13/16] move utils to linux

---
 libc/src/unistd/linux/CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 8b06498b0dd7d..51aa6b0d35b6d 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -116,7 +116,7 @@ add_entrypoint_object(
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
-    libc.src.unistd.pathconf_utils
+    libc.src.unistd.linux.pathconf_utils
 )
 
 add_entrypoint_object(
@@ -298,7 +298,7 @@ add_entrypoint_object(
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
-    libc.src.unistd.pathconf_utils
+    libc.src.unistd.linux.pathconf_utils
 )
 
 add_object_library(

>From f57f0037587b638ead5ecdfc26ec002eaba318f7 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Thu, 13 Jun 2024 23:32:05 -0400
Subject: [PATCH 14/16] move header to linux

---
 libc/src/unistd/linux/CMakeLists.txt         | 2 +-
 libc/src/unistd/{ => linux}/pathconf_utils.h | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename libc/src/unistd/{ => linux}/pathconf_utils.h (100%)

diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 51aa6b0d35b6d..62288715d8a93 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -306,7 +306,7 @@ add_object_library(
   SRCS
     pathconf_utils.cpp
   HDRS
-    ../pathconf_utils.h
+    pathconf_utils.h
   DEPENDS
     libc.include.unistd
     libc.include.sys_syscall
diff --git a/libc/src/unistd/pathconf_utils.h b/libc/src/unistd/linux/pathconf_utils.h
similarity index 100%
rename from libc/src/unistd/pathconf_utils.h
rename to libc/src/unistd/linux/pathconf_utils.h

>From 65ff5e6ff2584fbe463606656100f6413552af2b Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 15 Jun 2024 12:38:27 -0400
Subject: [PATCH 15/16] aplly new patch

---
 libc/hdr/CMakeLists.txt                       | 18 +++++++++++
 libc/hdr/sys_stat_macros.h                    | 22 ++++++++++++++
 libc/hdr/unistd_macros.h                      | 22 ++++++++++++++
 .../llvm-libc-macros/linux/unistd-macros.h    | 30 +++++++++++++++++++
 libc/src/unistd/linux/CMakeLists.txt          |  4 +--
 libc/src/unistd/linux/fpathconf.cpp           | 10 +++----
 libc/src/unistd/linux/pathconf.cpp            | 13 ++++----
 libc/src/unistd/linux/pathconf_utils.cpp      | 25 +++++++++++-----
 libc/src/unistd/linux/pathconf_utils.h        |  7 ++---
 libc/src/unistd/pathconf.h                    |  2 +-
 libc/test/src/unistd/CMakeLists.txt           | 28 +++++++++++++++++
 libc/test/src/unistd/fpathconf_test.cpp       | 11 +++++--
 libc/test/src/unistd/pathconf_test.cpp        | 10 +++++--
 13 files changed, 169 insertions(+), 33 deletions(-)
 create mode 100644 libc/hdr/sys_stat_macros.h
 create mode 100644 libc/hdr/unistd_macros.h

diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index 179b05e6ee966..9d8161d4225c2 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -68,4 +68,22 @@ add_proxy_header_library(
     libc.include.llvm-libc-macros.sys_epoll_macros
 )
 
+add_proxy_header_library(
+  sys_stat_macros
+  HDRS
+    sys_stat_macros.h
+  FULL_BUILD_DEPENDS
+    libc.include.sys_stat
+    libc.include.llvm-libc-macros.sys_stat_macros
+)
+
+add_proxy_header_library(
+  unistd_macros
+  HDRS
+    unistd_macros.h
+  FULL_BUILD_DEPENDS
+    libc.include.unistd
+    libc.include.llvm-libc-macros.unistd_macros
+)
+
 add_subdirectory(types)
diff --git a/libc/hdr/sys_stat_macros.h b/libc/hdr/sys_stat_macros.h
new file mode 100644
index 0000000000000..088e6908363a2
--- /dev/null
+++ b/libc/hdr/sys_stat_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros from sys/stat.h -----------------------------===//
+//
+// 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_HDR_SYS_STAT_MACROS_H
+#define LLVM_LIBC_HDR_SYS_STAT_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/sys-stat-macros.h"
+
+#else // Overlay mode
+
+#include <sys/stat.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_SYS_STAT_MACROS_H
diff --git a/libc/hdr/unistd_macros.h b/libc/hdr/unistd_macros.h
new file mode 100644
index 0000000000000..132e123280139
--- /dev/null
+++ b/libc/hdr/unistd_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros from unistd.h --------------------------------===//
+//
+// 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_HDR_UNISTD_MACROS_H
+#define LLVM_LIBC_HDR_UNISTD_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/unistd-macros.h"
+
+#else // Overlay mode
+
+#include <unistd.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_UNISTD_MACROS_H
diff --git a/libc/include/llvm-libc-macros/linux/unistd-macros.h b/libc/include/llvm-libc-macros/linux/unistd-macros.h
index c5109df435e68..eb4c94ac22d88 100644
--- a/libc/include/llvm-libc-macros/linux/unistd-macros.h
+++ b/libc/include/llvm-libc-macros/linux/unistd-macros.h
@@ -18,6 +18,36 @@
 #define _SC_PAGESIZE 1
 #define _SC_PAGE_SIZE _SC_PAGESIZE
 
+#define _PC_FILESIZEBITS 0
+#define _PC_LINK_MAX 1
+#define _PC_MAX_CANON 2
+#define _PC_MAX_INPUT 3
+#define _PC_NAME_MAX 4
+#define _PC_PATH_MAX 5
+#define _PC_PIPE_BUF 6
+#define _PC_2_SYMLINKS 7
+#define _PC_ALLOC_SIZE_MIN 8
+#define _PC_REC_INCR_XFER_SIZE 9
+#define _PC_REC_MAX_XFER_SIZE 10
+#define _PC_REC_MIN_XFER_SIZE 11
+#define _PC_REC_XFER_ALIGN 12
+#define _PC_SYMLINK_MAX 13
+#define _PC_CHOWN_RESTRICTED 14
+#define _PC_NO_TRUNC 15
+#define _PC_VDISABLE 16
+#define _PC_ASYNC_IO 17
+#define _PC_PRIO_IO 18
+#define _PC_SYNC_IO 19
+
+// TODO: Move these limit macros to a separate file
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_MAX_CANON 255
+#define _POSIX_MAX_INPUT 255
+#define _POSIX_PATH_MAX 256
+#define _POSIX_PIPE_BUF 512
+#define _POSIX_NO_TRUNC 1
+#define _POSIX_VDISABLE '\0'
+
 // Macro to set up the call to the __llvm_libc_syscall function
 // This is to prevent the call from having fewer than 6 arguments, since six
 // arguments are always passed to the syscall. Unnecessary arguments are
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 62288715d8a93..fb55dfb05f4ad 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -308,10 +308,10 @@ add_object_library(
   HDRS
     pathconf_utils.h
   DEPENDS
-    libc.include.unistd
-    libc.include.sys_syscall
+    libc.hdr.unistd_macros
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
+    libc.src.sys.statvfs.linux.statfs_utils
 )
 
 add_entrypoint_object(
diff --git a/libc/src/unistd/linux/fpathconf.cpp b/libc/src/unistd/linux/fpathconf.cpp
index 14a37da9e1637..6643ed1cc9e88 100644
--- a/libc/src/unistd/linux/fpathconf.cpp
+++ b/libc/src/unistd/linux/fpathconf.cpp
@@ -6,17 +6,17 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/unistd/fpathconf.h"
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
-#include "src/unistd/pathconf_utils.h"
-
-#include "src/errno/libc_errno.h"
-#include <sys/syscall.h> // For syscall numbers.
+#include "src/sys/statvfs/linux/statfs_utils.h"
+#include "src/unistd/linux/pathconf_utils.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
-  if (cpp::optional<LinuxStatFs> result = linux_fstatfs(fd))
+  if (cpp::optional<statfs_utils::LinuxStatFs> result =
+          statfs_utils::linux_fstatfs(fd))
     return pathconfig(result.value(), name);
   return -1;
 }
diff --git a/libc/src/unistd/linux/pathconf.cpp b/libc/src/unistd/linux/pathconf.cpp
index cb4457b7d29d7..09d4bb0ddb65d 100644
--- a/libc/src/unistd/linux/pathconf.cpp
+++ b/libc/src/unistd/linux/pathconf.cpp
@@ -6,17 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/unistd/pathconf.h"
 #include "src/errno/libc_errno.h"
-#include "src/unistd/pathconf_utils.h"
-
-#include <stdint.h> // For uint64_t.
-#include <sys/fstatvfs.h>
-#include <sys/syscall.h> // For syscall numbers.
+#include "src/sys/statvfs/linux/statfs_utils.h"
+#include "src/unistd/linux/pathconf_utils.h"
 
 namespace LIBC_NAMESPACE {
 
-LLVM_LIBC_FUNCTION(long, pathconf, (char *path, int name)) {
-  if (cpp::optional<LinuxStatFs> result = linux_statfs(const char *path);) {
+LLVM_LIBC_FUNCTION(long, pathconf, (const char *path, int name)) {
+  if (cpp::optional<statfs_utils::LinuxStatFs> result =
+          statfs_utils::linux_statfs(path)) {
     return pathconfig(result.value(), name);
   }
   return -1;
diff --git a/libc/src/unistd/linux/pathconf_utils.cpp b/libc/src/unistd/linux/pathconf_utils.cpp
index 7849230555aeb..6903fcd9e24d3 100644
--- a/libc/src/unistd/linux/pathconf_utils.cpp
+++ b/libc/src/unistd/linux/pathconf_utils.cpp
@@ -8,13 +8,22 @@
 
 #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.
+#include "src/sys/statvfs/linux/statfs_utils.h"
+#include <linux/bfs_fs.h>
+#if __has_include(<linux/ufs_fs.h>)
+#include <linux/ufs_fs.h>
+#else
+// from https://elixir.bootlin.com/linux/latest/source/fs/ufs/ufs_fs.h
+#define UFS_MAGIC 0x00011954
+#endif
+#include "hdr/unistd_macros.h"
+#include <linux/limits.h> // For LINK_MAX and other limits
+#include <linux/magic.h>  // For common FS magics
 
 namespace LIBC_NAMESPACE {
 
-long filesizebits(const struct statfs &s) {
+long filesizebits(const statfs_utils::LinuxStatFs &s) {
   switch (s.f_type) {
   case JFFS2_SUPER_MAGIC:
   case MSDOS_SUPER_MAGIC:
@@ -24,7 +33,7 @@ long filesizebits(const struct statfs &s) {
   return 64;
 }
 
-long link_max(const struct statfs &s) {
+long link_max(const statfs_utils::LinuxStatFs &s) {
   switch (s.f_type) {
   case EXT2_SUPER_MAGIC:
     return 32000;
@@ -40,7 +49,7 @@ long link_max(const struct statfs &s) {
   return LINK_MAX;
 }
 
-long _2_symlinks(const struct statfs &s) {
+long _2_symlinks(const statfs_utils::LinuxStatFs &s) {
   switch (s.f_type) {
   case ADFS_SUPER_MAGIC:
   case BFS_MAGIC:
@@ -53,7 +62,7 @@ long _2_symlinks(const struct statfs &s) {
   return 1;
 }
 
-long pathconfig(const struct fstatfs &s, int name) {
+long pathconfig(const statfs_utils::LinuxStatFs &s, int name) {
   switch (name) {
   case _PC_LINK_MAX:
     return link_max(s);
@@ -78,7 +87,7 @@ long pathconfig(const struct fstatfs &s, int name) {
     return _POSIX_MAX_INPUT;
 
   case _PC_NAME_MAX:
-    return s.f_namemax;
+    return s.f_namelen;
 
   case _PC_PATH_MAX:
     return _POSIX_PATH_MAX;
@@ -104,7 +113,7 @@ long pathconfig(const struct fstatfs &s, int name) {
     return -1;
 
   default:
-    errno = EINVAL;
+    libc_errno = EINVAL;
     return -1;
   }
 }
diff --git a/libc/src/unistd/linux/pathconf_utils.h b/libc/src/unistd/linux/pathconf_utils.h
index 468f3f94e1844..2c0ec0ea292f4 100644
--- a/libc/src/unistd/linux/pathconf_utils.h
+++ b/libc/src/unistd/linux/pathconf_utils.h
@@ -9,14 +9,11 @@
 #ifndef LLVM_LIBC_SRC_UNISTD_PATHCONF_UTILS_H
 #define LLVM_LIBC_SRC_UNISTD_PATHCONF_UTILS_H
 
-#include <unistd.h>
+#include "src/sys/statvfs/linux/statfs_utils.h"
 
 namespace LIBC_NAMESPACE {
 
-long filesizebits(const struct statfs &s);
-long link_max(const struct statfs &s);
-long _2_symlinks(const struct statfs &s);
-long pathconfig(const struct fstatfs &s, int name);
+long pathconfig(const statfs_utils::LinuxStatFs &s, int name);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/unistd/pathconf.h b/libc/src/unistd/pathconf.h
index a397cd9323bbb..2281f76f6aa69 100644
--- a/libc/src/unistd/pathconf.h
+++ b/libc/src/unistd/pathconf.h
@@ -13,7 +13,7 @@
 
 namespace LIBC_NAMESPACE {
 
-long pathconf(char *path, int name);
+long pathconf(const char *path, int name);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index de3e8d9ccbb62..d8c29f2252c90 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -446,6 +446,34 @@ add_libc_unittest(
     libc.src.unistd.sysconf
 )
 
+add_libc_unittest(
+  fpathconf_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    fpathconf_test.cpp
+  DEPENDS
+    libc.hdr.unistd_macros
+    libc.hdr.sys_stat_macros
+    libc.src.unistd.fpathconf
+    libc.src.fcntl.open
+    libc.src.unistd.close
+)
+
+add_libc_unittest(
+  pathconf_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    pathconf_test.cpp
+  DEPENDS
+    libc.hdr.unistd_macros
+    libc.hdr.sys_stat_macros
+    libc.src.unistd.pathconf
+    libc.src.fcntl.open
+    libc.src.unistd.close
+)
+
 add_libc_test(
   getopt_test
   HERMETIC_TEST_ONLY # Uses libc's own stderr
diff --git a/libc/test/src/unistd/fpathconf_test.cpp b/libc/test/src/unistd/fpathconf_test.cpp
index f51115981022f..43225ed39ff05 100644
--- a/libc/test/src/unistd/fpathconf_test.cpp
+++ b/libc/test/src/unistd/fpathconf_test.cpp
@@ -6,9 +6,12 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "hdr/unistd_macros.h"
+#include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/fpathconf.h"
-
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
@@ -18,8 +21,10 @@ TEST(LlvmLibcPipeTest, SmokeTest) {
   constexpr const char *FILENAME = "fpathconf.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
-  ASSERT_EQ(LIBC_NAMESPACE::pathconf(fd, _PC_SYNC_IO), -1);
-  ASSERT_EQ(LIBC_NAMESPACE::pathconf(fd, _PC_PATH_MAX), _POSIX_PATH_MAX);
+  EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_SYNC_IO), -1l);
+  EXPECT_EQ(LIBC_NAMESPACE::fpathconf(fd, _PC_PATH_MAX),
+            static_cast<long>(_POSIX_PATH_MAX));
+  LIBC_NAMESPACE::close(fd);
 }
 
 // TODO: Functionality tests
diff --git a/libc/test/src/unistd/pathconf_test.cpp b/libc/test/src/unistd/pathconf_test.cpp
index 178c683a36454..cfd0a191a5583 100644
--- a/libc/test/src/unistd/pathconf_test.cpp
+++ b/libc/test/src/unistd/pathconf_test.cpp
@@ -5,6 +5,10 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+#include "hdr/fcntl_macros.h"
+#include "hdr/unistd_macros.h"
+#include "llvm-libc-macros/sys-stat-macros.h"
+#include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/pathconf.h"
 
@@ -17,8 +21,10 @@ TEST(LlvmLibcPipeTest, SmokeTest) {
   constexpr const char *FILENAME = "fpathconf.test";
   auto TEST_FILE = libc_make_test_file_path(FILENAME);
   int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
-  ASSERT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_SYNC_IO), -1);
-  ASSERT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_PATH_MAX), _POSIX_PATH_MAX);
+  EXPECT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_SYNC_IO), -1l);
+  EXPECT_EQ(LIBC_NAMESPACE::pathconf(FILENAME, _PC_PATH_MAX),
+            static_cast<long>(_POSIX_PATH_MAX));
+  LIBC_NAMESPACE::close(fd);
 }
 
 // TODO: Functionality tests

>From 6af318bf25ccf6a8bdc5b3f5444e669db7c07ea8 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 16 Jun 2024 11:55:50 -0700
Subject: [PATCH 16/16] fix build issue

---
 libc/hdr/CMakeLists.txt                       |  9 ++++++++
 libc/hdr/limits_macros.h                      | 22 +++++++++++++++++++
 libc/hdr/sys_stat_macros.h                    |  2 +-
 libc/include/llvm-libc-macros/limits-macros.h | 12 ++++++++++
 .../llvm-libc-macros/linux/unistd-macros.h    |  3 ---
 libc/src/unistd/linux/CMakeLists.txt          |  1 +
 libc/src/unistd/linux/pathconf_utils.cpp      |  1 +
 libc/test/src/unistd/CMakeLists.txt           |  2 ++
 libc/test/src/unistd/fpathconf_test.cpp       |  1 +
 libc/test/src/unistd/pathconf_test.cpp        |  1 +
 10 files changed, 50 insertions(+), 4 deletions(-)
 create mode 100644 libc/hdr/limits_macros.h

diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index 76ec3e6fc010f..1303280c2c5ef 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -115,4 +115,13 @@ add_proxy_header_library(
     libc.include.float
 )
 
+add_proxy_header_library(
+  limits_macros
+  HDRS
+    limits_macros.h
+  FULL_BUILD_DEPENDS
+    libc.include.limits
+    libc.include.llvm-libc-macros.limits_macros
+)
+
 add_subdirectory(types)
diff --git a/libc/hdr/limits_macros.h b/libc/hdr/limits_macros.h
new file mode 100644
index 0000000000000..2dc13b0cca60d
--- /dev/null
+++ b/libc/hdr/limits_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros from limits.h --------------------------------===//
+//
+// 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_HDR_LIMITS_MACROS_H
+#define LLVM_LIBC_HDR_LIMITS_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/limits-macros.h"
+
+#else // Overlay mode
+
+#include <limits.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_LIMITS_MACROS_H
diff --git a/libc/hdr/sys_stat_macros.h b/libc/hdr/sys_stat_macros.h
index 088e6908363a2..cb58d62e1ffb7 100644
--- a/libc/hdr/sys_stat_macros.h
+++ b/libc/hdr/sys_stat_macros.h
@@ -1,4 +1,4 @@
-//===-- Definition of macros from sys/stat.h -----------------------------===//
+//===-- Definition of macros from sys/stat.h ------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/include/llvm-libc-macros/limits-macros.h b/libc/include/llvm-libc-macros/limits-macros.h
index 3fab996b61ac9..456487e603b25 100644
--- a/libc/include/llvm-libc-macros/limits-macros.h
+++ b/libc/include/llvm-libc-macros/limits-macros.h
@@ -225,4 +225,16 @@
 #define ULLONG_MIN 0ULL
 #endif // ULLONG_MIN
 
+#ifndef _POSIX_MAX_CANON
+#define _POSIX_MAX_CANON 255
+#endif
+
+#ifndef _POSIX_MAX_INPUT
+#define _POSIX_MAX_INPUT 255
+#endif
+
+#ifndef _POSIX_NAME_MAX
+#define _POSIX_PATH_MAX 256
+#endif
+
 #endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H
diff --git a/libc/include/llvm-libc-macros/linux/unistd-macros.h b/libc/include/llvm-libc-macros/linux/unistd-macros.h
index eb4c94ac22d88..a4c8e3cd91f7e 100644
--- a/libc/include/llvm-libc-macros/linux/unistd-macros.h
+++ b/libc/include/llvm-libc-macros/linux/unistd-macros.h
@@ -41,9 +41,6 @@
 
 // TODO: Move these limit macros to a separate file
 #define _POSIX_CHOWN_RESTRICTED 1
-#define _POSIX_MAX_CANON 255
-#define _POSIX_MAX_INPUT 255
-#define _POSIX_PATH_MAX 256
 #define _POSIX_PIPE_BUF 512
 #define _POSIX_NO_TRUNC 1
 #define _POSIX_VDISABLE '\0'
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index fb55dfb05f4ad..7e733d7f002c3 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -308,6 +308,7 @@ add_object_library(
   HDRS
     pathconf_utils.h
   DEPENDS
+    libc.hdr.limits_macros
     libc.hdr.unistd_macros
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
diff --git a/libc/src/unistd/linux/pathconf_utils.cpp b/libc/src/unistd/linux/pathconf_utils.cpp
index 6903fcd9e24d3..dc2f58e21d736 100644
--- a/libc/src/unistd/linux/pathconf_utils.cpp
+++ b/libc/src/unistd/linux/pathconf_utils.cpp
@@ -17,6 +17,7 @@
 // from https://elixir.bootlin.com/linux/latest/source/fs/ufs/ufs_fs.h
 #define UFS_MAGIC 0x00011954
 #endif
+#include "hdr/limits_macros.h"
 #include "hdr/unistd_macros.h"
 #include <linux/limits.h> // For LINK_MAX and other limits
 #include <linux/magic.h>  // For common FS magics
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index d8c29f2252c90..1a1e01e50f4e8 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -453,6 +453,7 @@ add_libc_unittest(
   SRCS
     fpathconf_test.cpp
   DEPENDS
+    libc.hdr.limits_macros
     libc.hdr.unistd_macros
     libc.hdr.sys_stat_macros
     libc.src.unistd.fpathconf
@@ -467,6 +468,7 @@ add_libc_unittest(
   SRCS
     pathconf_test.cpp
   DEPENDS
+    libc.hdr.limits_macros
     libc.hdr.unistd_macros
     libc.hdr.sys_stat_macros
     libc.src.unistd.pathconf
diff --git a/libc/test/src/unistd/fpathconf_test.cpp b/libc/test/src/unistd/fpathconf_test.cpp
index 43225ed39ff05..cf3f4ec700fa7 100644
--- a/libc/test/src/unistd/fpathconf_test.cpp
+++ b/libc/test/src/unistd/fpathconf_test.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "hdr/fcntl_macros.h"
+#include "hdr/limits_macros.h"
 #include "hdr/sys_stat_macros.h"
 #include "hdr/unistd_macros.h"
 #include "src/fcntl/open.h"
diff --git a/libc/test/src/unistd/pathconf_test.cpp b/libc/test/src/unistd/pathconf_test.cpp
index cfd0a191a5583..85c41c63531c9 100644
--- a/libc/test/src/unistd/pathconf_test.cpp
+++ b/libc/test/src/unistd/pathconf_test.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "hdr/fcntl_macros.h"
+#include "hdr/limits_macros.h"
 #include "hdr/unistd_macros.h"
 #include "llvm-libc-macros/sys-stat-macros.h"
 #include "src/fcntl/open.h"



More information about the libc-commits mailing list