[libc-commits] [libc] [libc] Support dynamically-grown lines in FlatFileDatabase (PR #223811)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Wed Sep 16 12:01:36 PDT 2026


================
@@ -16,27 +16,37 @@
 
 #include "hdr/errno_macros.h"
 #include "hdr/stdio_macros.h"
+#include "hdr/types/off_t.h"
 #include "hdr/types/size_t.h"
 #include "src/__support/CPP/functional.h"
+#include "src/__support/CPP/limits.h"
 #include "src/__support/CPP/span.h"
 #include "src/__support/File/file.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/pwd/dynamic_buffer.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace pwd {
 
+// Struct to hold the result of a line read operation.
 struct ReadLineResult {
   size_t bytes_read;
+  size_t raw_bytes_consumed;
   bool truncated;
-  // True only when no data was read because the file stream reached EOF.
+  // True only when zero bytes were read because the stream was already at EOF.
+  // A final line without a trailing newline returns bytes_read > 0 and
+  // eof == false; the following call returns bytes_read == 0 and eof == true.
   bool eof;
 };
 
-// Forward declaration of record parser for flat database files.
+// Parses a record in place and fills entry.
+// If the buffer is too small for auxiliary structures (such as pointer arrays),
+// specializations must return Error(ERANGE) prior to modifying the buffer.
 template <typename EntryType>
-bool parse_line(cpp::span<char> line, EntryType *entry);
+ErrorOr<void> parse_line(cpp::span<char> buffer, size_t line_len,
----------------
kaladron wrote:

You're right, line_len shouldn't be there. It was doing double-duty marking the end of the line and the start of the trailing scratch space, which parse_line<struct group> in the next patch needs in order to place the gr_mem[] pointer array into the caller's buffer.

I've split it explicitly into separate line and scratch spans, similar to FreeBSD's [__gr_parse_entry](https://github.com/freebsd/freebsd-src/blob/main/lib/libc/gen/getgrent.c#L1535)
: line has the exact record length (including the terminating null byte), scratch is passed as empty for passwd, and the ERANGE-on-insufficient-scratch growth contract is explicit in the signature and exercised by a new unit test.

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


More information about the libc-commits mailing list