implemented qdb_memfd_fill_fd function to enhance file descriptor writing using FFI
Some checks failed
PHPUnit / test (push) Has been cancelled
Some checks failed
PHPUnit / test (push) Has been cancelled
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user