[libc-commits] [libc] [libc] Modernize and extend dirent.h header. (PR #212902)

Alexey Samsonov via libc-commits libc-commits at lists.llvm.org
Wed Jul 29 17:00:06 PDT 2026


https://github.com/vonosmas created https://github.com/llvm/llvm-project/pull/212902

Extend the `<dirent.h>` header with macro and types specified in recent POSIX.1-2024:
* Add `posix_dent` structure, which has more fields than `dirent`, that are actually used in practice. This struct would be identical to `dirent` that we have on Linux
* Add `reclen_t` type for `d_reclen` field.
* Add macro `DT_BLK` and friends

Also, extend the tests to verify the values of `d_type` field, now that we have the proper macro defined.

Assisted by: Gemini, human-verified


>From e4856398248c6960370a24a9cb59ec798eb924f9 Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Wed, 29 Jul 2026 23:50:27 +0000
Subject: [PATCH] [libc] Modernize and extend dirent.h header.

---
 libc/include/CMakeLists.txt                   |  5 +++
 libc/include/dirent.yaml                      | 21 +++++++++++
 libc/include/llvm-libc-macros/CMakeLists.txt  |  6 ++++
 libc/include/llvm-libc-macros/dirent-macros.h | 21 +++++++++++
 .../llvm-libc-macros/linux/CMakeLists.txt     |  6 ++++
 .../llvm-libc-macros/linux/dirent-macros.h    | 26 ++++++++++++++
 libc/include/llvm-libc-types/CMakeLists.txt   |  4 ++-
 libc/include/llvm-libc-types/reclen_t.h       | 19 ++++++++++
 libc/include/llvm-libc-types/struct_dirent.h  |  3 +-
 .../llvm-libc-types/struct_posix_dent.h       | 35 +++++++++++++++++++
 libc/test/src/dirent/dirent_test.cpp          | 16 ++++++---
 11 files changed, 156 insertions(+), 6 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/dirent-macros.h
 create mode 100644 libc/include/llvm-libc-macros/linux/dirent-macros.h
 create mode 100644 libc/include/llvm-libc-types/reclen_t.h
 create mode 100644 libc/include/llvm-libc-types/struct_posix_dent.h

diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 37d2dc3142c4e..4cfaa73f61d1c 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -47,6 +47,11 @@ add_header_macro(
     .llvm-libc-types.ino_t
     .llvm-libc-types.DIR
     .llvm-libc-types.struct_dirent
+    .llvm-libc-types.struct_posix_dent
+    .llvm-libc-types.reclen_t
+    .llvm-libc-types.size_t
+    .llvm-libc-types.ssize_t
+    .llvm-libc-macros.dirent_macros
 )
 
 add_header_macro(
diff --git a/libc/include/dirent.yaml b/libc/include/dirent.yaml
index 66570bca6c495..e752b564d8d44 100644
--- a/libc/include/dirent.yaml
+++ b/libc/include/dirent.yaml
@@ -1,10 +1,31 @@
 header: dirent.h
 standards:
   - posix
+macros:
+  - macro_name: DT_UNKNOWN
+    macro_header: dirent-macros.h
+  - macro_name: DT_FIFO
+    macro_header: dirent-macros.h
+  - macro_name: DT_CHR
+    macro_header: dirent-macros.h
+  - macro_name: DT_DIR
+    macro_header: dirent-macros.h
+  - macro_name: DT_BLK
+    macro_header: dirent-macros.h
+  - macro_name: DT_REG
+    macro_header: dirent-macros.h
+  - macro_name: DT_LNK
+    macro_header: dirent-macros.h
+  - macro_name: DT_SOCK
+    macro_header: dirent-macros.h
 types:
   - type_name: struct_dirent
+  - type_name: struct_posix_dent
   - type_name: DIR
   - type_name: ino_t
+  - type_name: reclen_t
+  - type_name: size_t
+  - type_name: ssize_t
 functions:
   - name: alphasort
     standards:
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 3e7bdd1bed7a6..f0f9dabb00433 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -72,6 +72,12 @@ add_macro_header(
     null-macro.h
 )
 
+add_macro_header(
+  dirent_macros
+  HDR
+    dirent-macros.h
+)
+
 add_macro_header(
   fcntl_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/dirent-macros.h b/libc/include/llvm-libc-macros/dirent-macros.h
new file mode 100644
index 0000000000000..b93f9e6e74f58
--- /dev/null
+++ b/libc/include/llvm-libc-macros/dirent-macros.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of macros from dirent.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_DIRENT_MACROS_H
+#define LLVM_LIBC_MACROS_DIRENT_MACROS_H
+
+#ifdef __linux__
+#include "linux/dirent-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_DIRENT_MACROS_H
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 374e7e6159a5d..2a400b1c80e2c 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -4,6 +4,12 @@ add_header(
     error-number-macros.h
 )
 
+add_header(
+  dirent_macros
+  HDR
+    dirent-macros.h
+)
+
 add_header(
   fcntl_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/dirent-macros.h b/libc/include/llvm-libc-macros/linux/dirent-macros.h
new file mode 100644
index 0000000000000..7d9347593a4a2
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/dirent-macros.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of macros from dirent.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
+
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+
+#endif // LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 9dd7548aa5126..aae93bd905e36 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -11,6 +11,7 @@ add_header(
     .size_t
     libc.include.llvm-libc-macros.annex_k_macros
 )
+add_header(reclen_t HDR reclen_t.h)
 add_header(ssize_t HDR ssize_t.h)
 add_header(__atfork_callback_t HDR __atfork_callback_t.h)
 add_header(__search_compare_t HDR __search_compare_t.h)
@@ -122,7 +123,8 @@ add_header(time_t HDR time_t_64.h DEST_HDR time_t.h)
 add_header(sighandler_t HDR sighandler_t.h)
 add_header(stack_t HDR stack_t.h DEPENDS .size_t)
 add_header(suseconds_t HDR suseconds_t.h)
-add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
+add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t .reclen_t)
+add_header(struct_posix_dent HDR struct_posix_dent.h DEPENDS .ino_t .off_t .reclen_t)
 add_header(struct_dl_phdr_info HDR struct_dl_phdr_info.h DEPENDS .size_t libc.include.llvm-libc-macros.link_macros)
 add_header(dl_info HDR Dl_info.h)
 add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
diff --git a/libc/include/llvm-libc-types/reclen_t.h b/libc/include/llvm-libc-types/reclen_t.h
new file mode 100644
index 0000000000000..64a028ee62617
--- /dev/null
+++ b/libc/include/llvm-libc-types/reclen_t.h
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of reclen_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_RECLEN_T_H
+#define LLVM_LIBC_TYPES_RECLEN_T_H
+
+typedef unsigned short reclen_t;
+
+#endif // LLVM_LIBC_TYPES_RECLEN_T_H
diff --git a/libc/include/llvm-libc-types/struct_dirent.h b/libc/include/llvm-libc-types/struct_dirent.h
index f950869fc77dd..0272e76369d4c 100644
--- a/libc/include/llvm-libc-types/struct_dirent.h
+++ b/libc/include/llvm-libc-types/struct_dirent.h
@@ -11,12 +11,13 @@
 
 #include "ino_t.h"
 #include "off_t.h"
+#include "reclen_t.h"
 
 struct dirent {
   ino_t d_ino;
 #ifdef __linux__
   off_t d_off;
-  unsigned short d_reclen;
+  reclen_t d_reclen;
 #endif
   unsigned char d_type;
   // The user code should use strlen to determine actual the size of d_name.
diff --git a/libc/include/llvm-libc-types/struct_posix_dent.h b/libc/include/llvm-libc-types/struct_posix_dent.h
new file mode 100644
index 0000000000000..0b46268506fe3
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_posix_dent.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of struct posix_dent.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
+#define LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
+
+#include "ino_t.h"
+#include "off_t.h"
+#include "reclen_t.h"
+
+struct posix_dent {
+  ino_t d_ino;
+#ifdef __linux__
+  off_t d_off;
+#endif
+  reclen_t d_reclen;
+  unsigned char d_type;
+  // The user code should use strlen to determine the actual size of d_name.
+  // Likewise, it is incorrect and prohibited by the POSIX standard to determine
+  // the size of struct posix_dent type using sizeof. The size should be got
+  // using a different method, for example, from the d_reclen field.
+  char d_name[1];
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
diff --git a/libc/test/src/dirent/dirent_test.cpp b/libc/test/src/dirent/dirent_test.cpp
index 2862b140ba8ed..05bcafbcfb403 100644
--- a/libc/test/src/dirent/dirent_test.cpp
+++ b/libc/test/src/dirent/dirent_test.cpp
@@ -34,14 +34,22 @@ TEST_F(LlvmLibcDirentTest, SimpleOpenAndRead) {
     struct ::dirent *d = LIBC_NAMESPACE::readdir(dir);
     if (d == nullptr)
       break;
-    if (string_view(&d->d_name[0]) == "file1.txt")
+    if (string_view(&d->d_name[0]) == "file1.txt") {
       file1 = d;
-    if (string_view(&d->d_name[0]) == "file2.txt")
+      EXPECT_EQ(d->d_type, static_cast<decltype(d->d_type)>(DT_REG));
+    }
+    if (string_view(&d->d_name[0]) == "file2.txt") {
       file2 = d;
-    if (string_view(&d->d_name[0]) == "dir1")
+      EXPECT_EQ(d->d_type, static_cast<decltype(d->d_type)>(DT_REG));
+    }
+    if (string_view(&d->d_name[0]) == "dir1") {
       dir1 = d;
-    if (string_view(&d->d_name[0]) == "dir2")
+      EXPECT_EQ(d->d_type, static_cast<decltype(d->d_type)>(DT_DIR));
+    }
+    if (string_view(&d->d_name[0]) == "dir2") {
       dir2 = d;
+      EXPECT_EQ(d->d_type, static_cast<decltype(d->d_type)>(DT_DIR));
+    }
   }
 
   // Verify that we don't break out of the above loop in error.



More information about the libc-commits mailing list