mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 07:33:20 +00:00
LibCore: Add a system wrapper to pipe a file
This uses splice on Linux and mmap+write elsewhere to transfer a file to a pipe. Note we cannot use sendfile because (at least on macOS) the receiving fd must be a socket.
This commit is contained in:
parent
62e52640d0
commit
e433dee543
Notes:
github-actions[bot]
2025-10-14 11:42:14 +00:00
Author: https://github.com/trflynn89
Commit: e433dee543
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6435
3 changed files with 35 additions and 0 deletions
|
@ -870,4 +870,27 @@ ErrorOr<void> set_close_on_exec(int fd, bool enabled)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<size_t> transfer_file_through_pipe(int source_fd, int target_fd, size_t source_offset, size_t source_length)
|
||||
{
|
||||
#if defined(AK_OS_LINUX)
|
||||
auto sent = ::splice(source_fd, reinterpret_cast<off_t*>(&source_offset), target_fd, nullptr, source_length, SPLICE_F_MOVE | SPLICE_F_NONBLOCK);
|
||||
if (sent < 0)
|
||||
return Error::from_syscall("send_file_to_pipe"sv, errno);
|
||||
return sent;
|
||||
#else
|
||||
static auto page_size = PAGE_SIZE;
|
||||
|
||||
// mmap requires the offset to be page-aligned, so we must handle that here.
|
||||
auto aligned_source_offset = (source_offset / page_size) * page_size;
|
||||
auto offset_adjustment = source_offset - aligned_source_offset;
|
||||
auto mapped_source_length = source_length + offset_adjustment;
|
||||
|
||||
// FIXME: We could use MappedFile here if we update it to support offsets and not auto-close the source fd.
|
||||
auto* mapped = TRY(mmap(nullptr, mapped_source_length, PROT_READ, MAP_SHARED, source_fd, aligned_source_offset));
|
||||
ScopeGuard guard { [&]() { (void)munmap(mapped, mapped_source_length); } };
|
||||
|
||||
return TRY(write(target_fd, { static_cast<u8*>(mapped) + offset_adjustment, source_length }));
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -190,4 +190,6 @@ bool is_socket(int fd);
|
|||
ErrorOr<void> sleep_ms(u32 milliseconds);
|
||||
ErrorOr<void> set_close_on_exec(int fd, bool enabled);
|
||||
|
||||
ErrorOr<size_t> transfer_file_through_pipe(int source_fd, int target_fd, size_t source_offset, size_t source_length);
|
||||
|
||||
}
|
||||
|
|
|
@ -403,4 +403,14 @@ ErrorOr<void> kill(pid_t pid, int signal)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<size_t> transfer_file_through_pipe(int source_fd, int target_fd, size_t source_offset, size_t source_length)
|
||||
{
|
||||
(void)source_fd;
|
||||
(void)target_fd;
|
||||
(void)source_offset;
|
||||
(void)source_length;
|
||||
|
||||
return Error::from_string_literal("FIXME: Implement System::transfer_file_through_pipe on Windows (for HTTP disk cache)");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue