From 23c99b6d2c935404863c43c1df88d0118209e8c3 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Fri, 22 Dec 2023 13:34:31 +0200 Subject: [PATCH] alnyan/yggdrasil: add FileMapping --- library/std/src/os/yggdrasil/io/mod.rs | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/library/std/src/os/yggdrasil/io/mod.rs b/library/std/src/os/yggdrasil/io/mod.rs index 12036fbae02..d0c2672a268 100644 --- a/library/std/src/os/yggdrasil/io/mod.rs +++ b/library/std/src/os/yggdrasil/io/mod.rs @@ -32,12 +32,64 @@ pub use raw::*; #[unstable(feature = "yggdrasil_os", issue = "none")] pub use poll::PollChannel; +#[unstable(feature = "yggdrasil_os", issue = "none")] +pub struct FileMapping<'a> { + data: &'a mut [u8], + _fd: OwnedFd, +} + #[unstable(feature = "yggdrasil_os", issue = "none")] pub trait FdDeviceRequest { #[unstable(feature = "yggdrasil_os", issue = "none")] unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()>; } +#[unstable(feature = "yggdrasil_os", issue = "none")] +impl<'a> FileMapping<'a> { + pub fn new>(f: F, offset: u64, len: usize) -> crate::io::Result { + use yggdrasil_rt::mem::MappingSource; + + let owned_fd = f.into(); + let raw_fd = owned_fd.as_raw_fd(); + let base = cvt_io(unsafe { + yggdrasil_rt::sys::map_memory(None, len, &MappingSource::File(raw_fd, offset)) + })?; + + #[allow(fuzzy_provenance_casts)] + let data = unsafe { crate::slice::from_raw_parts_mut(base as *mut u8, len) }; + + Ok(Self { data, _fd: owned_fd }) + } +} + +#[unstable(feature = "yggdrasil_os", issue = "none")] +impl crate::ops::Deref for FileMapping<'_> { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + self.data + } +} + +#[unstable(feature = "yggdrasil_os", issue = "none")] +impl crate::ops::DerefMut for FileMapping<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.data + } +} + +#[unstable(feature = "yggdrasil_os", issue = "none")] +impl Drop for FileMapping<'_> { + fn drop(&mut self) { + // Unmap the memory + let base = self.data.as_ptr() as usize; + let len = self.data.len(); + unsafe { + yggdrasil_rt::sys::unmap_memory(base, len).expect("Memory unmap failed"); + } + } +} + #[unstable(feature = "yggdrasil_os", issue = "none")] impl FdDeviceRequest for T { unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()> {