implemented qdb_memfd_fill_fd function to enhance file descriptor writing using FFI
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
2026-06-12 22:24:27 +02:00
parent 560ca69ae8
commit ebf27811db

View File

@ -113,6 +113,7 @@ function qdb_linux_libc_ffi() {
try { try {
$ffi = FFI::cdef( $ffi = FFI::cdef(
'int memfd_create(const char *name, unsigned int flags); 'int memfd_create(const char *name, unsigned int flags);
long write(int fd, const void *buf, unsigned long count);
int close(int fd);', int close(int fd);',
'libc.so.6' '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] * @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) { if ($fd < 0) {
return null; return null;
} }
$written = @file_put_contents('/proc/self/fd/' . $fd, $bytes); if (!qdb_memfd_fill_fd($fd, $bytes)) {
if ($written === false || $written !== strlen($bytes)) {
qdb_close_fd($fd); qdb_close_fd($fd);
return null; return null;
} }