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

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Fri Jun 14 09:13:14 PDT 2024


https://github.com/SchrodingerZhu requested changes to this pull request.

I tested locally and it does not work. Can you apply the following patch?

```diff
>From 1b5cefefd29b47ef2592317d9e27a0f1f6de7c05 Mon Sep 17 00:00:00 2001
From: Yifan Zhu <yifzhu at nvidia.com>
Date: Fri, 14 Jun 2024 09:10:15 -0700
Subject: [PATCH] fix

Signed-off-by: Yifan Zhu <yifzhu at nvidia.com>
---
 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 179b05e6ee96..9d8161d4225c 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 000000000000..088e6908363a
--- /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 000000000000..132e12328013
--- /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 c5109df435e6..eb4c94ac22d8 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 62288715d8a9..fb55dfb05f4a 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 14a37da9e163..6643ed1cc9e8 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 cb4457b7d29d..09d4bb0ddb65 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 7849230555ae..6903fcd9e24d 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 468f3f94e184..2c0ec0ea292f 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 a397cd9323bb..2281f76f6aa6 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 de3e8d9ccbb6..d8c29f2252c9 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 f51115981022..43225ed39ff0 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 178c683a3645..cfd0a191a558 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
-- 
2.34.1

```

@lntue @michaelrj-google Could you also take a look at this since it may need to include a patch from me.

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


More information about the libc-commits mailing list