mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
mmap skeleton
This commit is contained in:
1 parent
396812d66c
commit
cc4583ef50
4 files changed
+182
No files matched your search
Generated
+21
@@ -996,6 +996,15 @@ version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
@@ -1190,6 +1199,16 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978aa494585d3ca4ad74929863093e87cac9790d81fe7aba2b3dc2890643a0fc"
|
||||
|
||||
[[package]]
|
||||
name = "page_size"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
@@ -1719,6 +1738,7 @@ dependencies = [
|
||||
"libz-sys",
|
||||
"md-5",
|
||||
"memchr",
|
||||
"memmap2",
|
||||
"mt19937",
|
||||
"nix",
|
||||
"num-bigint",
|
||||
@@ -1729,6 +1749,7 @@ dependencies = [
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"page_size",
|
||||
"paste",
|
||||
"puruspe",
|
||||
"rand",
|
||||
|
||||
@@ -63,6 +63,8 @@ ahash = "0.7.6"
|
||||
libz-sys = { version = "1.1.5", optional = true }
|
||||
num_enum = "0.5.7"
|
||||
ascii = "1.0.0"
|
||||
memmap2 = "0.5.0"
|
||||
page_size = "0.4.2"
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "redox")))'.dependencies]
|
||||
termios = "0.3.3"
|
||||
|
||||
@@ -16,6 +16,8 @@ mod gc;
|
||||
mod hashlib;
|
||||
mod json;
|
||||
mod math;
|
||||
#[cfg(unix)]
|
||||
mod mmap;
|
||||
mod platform;
|
||||
mod pyexpat;
|
||||
mod pystruct;
|
||||
@@ -125,6 +127,7 @@ pub fn get_module_inits() -> impl Iterator<Item = (Cow<'static, str>, StdlibInit
|
||||
{
|
||||
"_posixsubprocess" => posixsubprocess::make_module,
|
||||
"syslog" => syslog::make_module,
|
||||
"mmap" => mmap::make_module,
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
pub(crate) use mmap::make_module;
|
||||
|
||||
#[pymodule]
|
||||
mod mmap {
|
||||
use crate::vm::{
|
||||
builtins::PyTypeRef, convert::ToPyResult, function::OptionalArg, types::Constructor,
|
||||
FromArgs, PyObject, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
use memmap2::{MmapMut, MmapOptions};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
enum AccessMode {
|
||||
Default = 0,
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
Copy = 3,
|
||||
}
|
||||
|
||||
impl TryFromBorrowedObject for AccessMode {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
|
||||
let i = u32::try_from_borrowed_object(vm, obj)?;
|
||||
Ok(match i {
|
||||
0 => Self::Default,
|
||||
1 => Self::Read,
|
||||
2 => Self::Write,
|
||||
3 => Self::Copy,
|
||||
_ => return Err(vm.new_value_error("Not a valid AccessMode value".to_owned())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
use libc::{MAP_ANON, MAP_ANONYMOUS, MAP_PRIVATE, MAP_SHARED, PROT_READ, PROT_WRITE};
|
||||
#[pyattr]
|
||||
const ACCESS_DEFAULT: u32 = AccessMode::Default as u32;
|
||||
#[pyattr]
|
||||
const ACCESS_READ: u32 = AccessMode::Read as u32;
|
||||
#[pyattr]
|
||||
const ACCESS_WRITE: u32 = AccessMode::Write as u32;
|
||||
#[pyattr]
|
||||
const ACCESS_COPY: u32 = AccessMode::Copy as u32;
|
||||
|
||||
#[pyattr(name = "PAGESIZE")]
|
||||
fn pagesize(vm: &VirtualMachine) -> usize {
|
||||
page_size::get()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "mmap")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
struct PyMmap {
|
||||
mmap: MmapMut,
|
||||
exports: usize,
|
||||
// PyObject *weakreflist;
|
||||
access: AccessMode,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
struct MmapNewArgs {
|
||||
#[pyarg(any)]
|
||||
fileno: std::os::unix::io::RawFd,
|
||||
#[pyarg(any)]
|
||||
length: isize,
|
||||
#[pyarg(any, default = "MAP_SHARED")]
|
||||
flags: libc::c_int,
|
||||
#[pyarg(any, default = "PROT_WRITE|PROT_READ")]
|
||||
prot: libc::c_int,
|
||||
#[pyarg(any, default = "AccessMode::Default")]
|
||||
access: AccessMode,
|
||||
#[pyarg(any, default = "0")]
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
impl Constructor for PyMmap {
|
||||
type Args = MmapNewArgs;
|
||||
|
||||
fn py_new(
|
||||
cls: PyTypeRef,
|
||||
MmapNewArgs {
|
||||
fileno: fd,
|
||||
length,
|
||||
flags,
|
||||
prot,
|
||||
access,
|
||||
offset,
|
||||
}: Self::Args,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
if length < 0 {
|
||||
return Err(
|
||||
vm.new_overflow_error("memory mapped length must be positive".to_owned())
|
||||
);
|
||||
}
|
||||
// if offset < 0 {
|
||||
// return Err(vm.new_overflow_error("memory mapped offset must be positive".to_owned()));
|
||||
// }
|
||||
if (access != AccessMode::Default)
|
||||
&& ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ)))
|
||||
{
|
||||
return Err(vm.new_value_error(
|
||||
"mmap can't specify both access and flags, prot.".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
let (flags, prot, access) = match access {
|
||||
AccessMode::Read => (MAP_SHARED, PROT_READ, access),
|
||||
AccessMode::Write => (MAP_SHARED, PROT_READ | PROT_WRITE, access),
|
||||
AccessMode::Copy => (MAP_PRIVATE, PROT_READ | PROT_WRITE, access),
|
||||
AccessMode::Default => {
|
||||
let access = if (prot & PROT_READ) != 0 && (prot & PROT_WRITE) != 0 {
|
||||
access
|
||||
} else if (prot & PROT_WRITE) != 0 {
|
||||
AccessMode::Write
|
||||
} else {
|
||||
AccessMode::Read
|
||||
};
|
||||
(flags, prot, access)
|
||||
}
|
||||
_ => return Err(vm.new_value_error("mmap invalid access parameter.".to_owned())),
|
||||
};
|
||||
|
||||
let mut mmap_opt = MmapOptions::new();
|
||||
let mmap_opt = mmap_opt.offset(offset);
|
||||
// .len(map_size)
|
||||
let mmap = match access {
|
||||
AccessMode::Write => unsafe { mmap_opt.map_mut(fd) },
|
||||
// AccessMode::Read => mmap_opt.map(fd),
|
||||
AccessMode::Copy => unsafe { mmap_opt.map_copy(fd) },
|
||||
_ => unreachable!("access must be decided before here"),
|
||||
}
|
||||
.map_err(|_| vm.new_value_error("FIXME: mmap error".to_owned()))?;
|
||||
|
||||
let m_obj = Self {
|
||||
mmap,
|
||||
exports: 0,
|
||||
access,
|
||||
};
|
||||
|
||||
m_obj.to_pyresult(vm)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyMmap {
|
||||
#[pymethod]
|
||||
fn close(&self) -> PyResult<()> {
|
||||
if self.exports > 0 {
|
||||
// PyErr_SetString(PyExc_BufferError, "cannot close "\
|
||||
// "exported pointers exist");
|
||||
}
|
||||
// self.mmap = MmapMut::map_anon(0).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user