From ebf27811db6d7642a24ab84720a29cb839f543c5 Mon Sep 17 00:00:00 2001 From: Tom Hempel Date: Fri, 12 Jun 2026 22:24:27 +0200 Subject: [PATCH] implemented qdb_memfd_fill_fd function to enhance file descriptor writing using FFI --- lib/read_db_cache.php | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/read_db_cache.php b/lib/read_db_cache.php index 6936c8a..d67fc48 100644 --- a/lib/read_db_cache.php +++ b/lib/read_db_cache.php @@ -113,6 +113,7 @@ function qdb_linux_libc_ffi() { try { $ffi = FFI::cdef( 'int memfd_create(const char *name, unsigned int flags); + long write(int fd, const void *buf, unsigned long count); int close(int fd);', 'libc.so.6' ); @@ -137,6 +138,38 @@ function qdb_close_fd(int $fd): void { } } +/** + * Fill a raw fd (e.g. memfd). /proc/self/fd/N writes are blocked on some hosts; + * fall back to libc write() via FFI. + */ +function qdb_memfd_fill_fd(int $fd, string $bytes): bool { + $len = strlen($bytes); + if ($len === 0) { + return true; + } + $written = @file_put_contents('/proc/self/fd/' . $fd, $bytes); + if ($written === $len) { + return true; + } + $ffi = qdb_linux_libc_ffi(); + if ($ffi === null) { + return false; + } + $offset = 0; + while ($offset < $len) { + $chunkLen = min(1024 * 1024, $len - $offset); + $chunk = substr($bytes, $offset, $chunkLen); + $buf = FFI::new('char[' . $chunkLen . ']'); + FFI::memcpy($buf, $chunk, $chunkLen); + $n = (int)$ffi->write($fd, $buf, $chunkLen); + if ($n <= 0) { + return false; + } + $offset += $n; + } + return true; +} + /** * @return array{0: int, 1: string}|null [fd, /proc/self/fd/N] */ @@ -151,8 +184,7 @@ function qdb_memfd_write(string $bytes): ?array { if ($fd < 0) { return null; } - $written = @file_put_contents('/proc/self/fd/' . $fd, $bytes); - if ($written === false || $written !== strlen($bytes)) { + if (!qdb_memfd_fill_fd($fd, $bytes)) { qdb_close_fd($fd); return null; }