Merge branch 'mmap2' into 'master'
Add mmap2 See merge request redox-os/syscall!52
This commit is contained in:
19
src/call.rs
19
src/call.rs
@@ -1,5 +1,5 @@
|
||||
use super::arch::*;
|
||||
use super::data::{Map, SigAction, Stat, StatVfs, TimeSpec};
|
||||
use super::data::{Map, Map2, SigAction, Stat, StatVfs, TimeSpec};
|
||||
use super::error::Result;
|
||||
use super::flag::*;
|
||||
use super::number::*;
|
||||
@@ -104,11 +104,26 @@ pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result<usiz
|
||||
unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), vars.as_ptr() as usize, vars.len()) }
|
||||
}
|
||||
|
||||
/// Map a file into memory
|
||||
/// Map a file into memory.
|
||||
pub unsafe fn fmap(fd: usize, map: &Map) -> Result<usize> {
|
||||
syscall3(SYS_FMAP, fd, map as *const Map as usize, mem::size_of::<Map>())
|
||||
}
|
||||
|
||||
///
|
||||
/// Map a file into memory, but with the ability to set the address to map into, either as a hint
|
||||
/// or as a requirement of the map.
|
||||
///
|
||||
/// # Errors
|
||||
/// `EACCES` - the file descriptor was not open for reading
|
||||
/// `EBADF` - if the file descriptor was invalid
|
||||
/// `ENODEV` - mmapping was not supported
|
||||
/// `EINVAL` - invalid combination of flags
|
||||
/// `EEXIST` - if [`MapFlags::MAP_FIXED`] was set, and the address specified was already in use.
|
||||
///
|
||||
pub unsafe fn fmap2(fd: usize, map: &Map2) -> Result<usize> {
|
||||
syscall3(SYS_FMAP2, fd, map as *const Map2 as usize, mem::size_of::<Map2>())
|
||||
}
|
||||
|
||||
/// Unmap a memory-mapped file
|
||||
pub unsafe fn funmap(addr: usize) -> Result<usize> {
|
||||
syscall1(SYS_FUNMAP, addr)
|
||||
|
||||
34
src/data.rs
34
src/data.rs
@@ -77,6 +77,40 @@ impl DerefMut for Map {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct Map2 {
|
||||
/// The offset inside the file that is being mapped.
|
||||
pub offset: usize,
|
||||
|
||||
/// The size of the memory map.
|
||||
pub size: usize,
|
||||
|
||||
/// Contains both prot and map flags.
|
||||
pub flags: MapFlags,
|
||||
|
||||
/// Functions as a hint to where in the virtual address space of the running process, to place
|
||||
/// the memory map. If [`MapFlags::MAP_FIXED`] is set, then this address must be the address to
|
||||
/// map to.
|
||||
pub address: usize,
|
||||
}
|
||||
|
||||
impl Deref for Map2 {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const Map2 as *const u8, mem::size_of::<Map2>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Map2 {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut Map2 as *mut u8, mem::size_of::<Map2>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
#[repr(C)]
|
||||
|
||||
@@ -74,6 +74,10 @@ bitflags! {
|
||||
|
||||
const MAP_SHARED = 0x0001;
|
||||
const MAP_PRIVATE = 0x0002;
|
||||
|
||||
/// Only accepted for mmap2(2).
|
||||
const MAP_FIXED = 0x0004;
|
||||
const MAP_FIXED_NOREPLACE = 0x000C;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55;
|
||||
pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927;
|
||||
pub const SYS_FEXEC: usize = SYS_CLASS_FILE | 11;
|
||||
pub const SYS_FMAP: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 90;
|
||||
pub const SYS_FMAP2: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 900;
|
||||
pub const SYS_FUNMAP: usize = SYS_CLASS_FILE | 91;
|
||||
pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928;
|
||||
pub const SYS_FRENAME: usize = SYS_CLASS_FILE | SYS_ARG_PATH | 38;
|
||||
|
||||
@@ -12,6 +12,7 @@ sed 's/trait Scheme/trait SchemeBlock/' scheme.rs \
|
||||
| sed 's/fn handle(\&self, packet: \&mut Packet)/fn handle(\&self, packet: \&Packet) -> Option<usize>/' \
|
||||
| sed 's/packet.a = Error::mux(res);/res.transpose().map(Error::mux)/' \
|
||||
| sed 's/\.map(|f| f\.bits())/\.map(|f| f.map(|f| f.bits()))/' \
|
||||
| sed 's/\.map(|o| o as usize)/.map(|o| o.map(|o| o as usize))/' \
|
||||
| sed 's/Result<\([^>]\+\)>/Result<Option<\1>>/g' \
|
||||
> scheme_block.rs
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ pub trait Scheme {
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FMAP2 => if packet.d >= mem::size_of::<Map2>() {
|
||||
self.fmap2(packet.b, unsafe { &*(packet.c as *const Map2) })
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FUNMAP => self.funmap(packet.b),
|
||||
SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid),
|
||||
@@ -120,6 +125,17 @@ pub trait Scheme {
|
||||
fn fmap(&self, id: usize, map: &Map) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn fmap2(&self, id: usize, map: &Map2) -> Result<usize> {
|
||||
if map.flags.contains(MapFlags::MAP_FIXED) {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
self.fmap(id, &Map {
|
||||
offset: map.offset,
|
||||
size: map.size,
|
||||
flags: map.flags,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn funmap(&self, address: usize) -> Result<usize> {
|
||||
|
||||
@@ -16,7 +16,7 @@ pub trait SchemeBlock {
|
||||
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c, packet.d),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c as isize, packet.d).map(|o| o.map(|o| o as usize)),
|
||||
SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16),
|
||||
SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32),
|
||||
SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d),
|
||||
@@ -26,6 +26,11 @@ pub trait SchemeBlock {
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FMAP2 => if packet.d >= mem::size_of::<Map2>() {
|
||||
self.fmap2(packet.b, unsafe { &*(packet.c as *const Map2) })
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FUNMAP => self.funmap(packet.b),
|
||||
SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid),
|
||||
@@ -92,7 +97,7 @@ pub trait SchemeBlock {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<Option<usize>> {
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<Option<isize>> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
@@ -120,6 +125,17 @@ pub trait SchemeBlock {
|
||||
fn fmap(&self, id: usize, map: &Map) -> Result<Option<usize>> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn fmap2(&self, id: usize, map: &Map2) -> Result<Option<usize>> {
|
||||
if map.flags.contains(MapFlags::MAP_FIXED) {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
self.fmap(id, &Map {
|
||||
offset: map.offset,
|
||||
size: map.size,
|
||||
flags: map.flags,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn funmap(&self, address: usize) -> Result<Option<usize>> {
|
||||
|
||||
@@ -16,7 +16,7 @@ pub trait SchemeBlockMut {
|
||||
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c, packet.d),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c as isize, packet.d).map(|o| o.map(|o| o as usize)),
|
||||
SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16),
|
||||
SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32),
|
||||
SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d),
|
||||
@@ -26,6 +26,11 @@ pub trait SchemeBlockMut {
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FMAP2 => if packet.d >= mem::size_of::<Map2>() {
|
||||
self.fmap2(packet.b, unsafe { &*(packet.c as *const Map2) })
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FUNMAP => self.funmap(packet.b),
|
||||
SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid),
|
||||
@@ -92,7 +97,7 @@ pub trait SchemeBlockMut {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<Option<usize>> {
|
||||
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result<Option<isize>> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
@@ -120,6 +125,17 @@ pub trait SchemeBlockMut {
|
||||
fn fmap(&mut self, id: usize, map: &Map) -> Result<Option<usize>> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn fmap2(&mut self, id: usize, map: &Map2) -> Result<Option<usize>> {
|
||||
if map.flags.contains(MapFlags::MAP_FIXED) {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
self.fmap(id, &Map {
|
||||
offset: map.offset,
|
||||
size: map.size,
|
||||
flags: map.flags,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn funmap(&mut self, address: usize) -> Result<Option<usize>> {
|
||||
|
||||
@@ -16,7 +16,7 @@ pub trait SchemeMut {
|
||||
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c, packet.d),
|
||||
SYS_LSEEK => self.seek(packet.b, packet.c as isize, packet.d).map(|o| o as usize),
|
||||
SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16),
|
||||
SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32),
|
||||
SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d),
|
||||
@@ -26,6 +26,11 @@ pub trait SchemeMut {
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FMAP2 => if packet.d >= mem::size_of::<Map2>() {
|
||||
self.fmap2(packet.b, unsafe { &*(packet.c as *const Map2) })
|
||||
} else {
|
||||
Err(Error::new(EFAULT))
|
||||
},
|
||||
SYS_FUNMAP => self.funmap(packet.b),
|
||||
SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
|
||||
SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid),
|
||||
@@ -92,7 +97,7 @@ pub trait SchemeMut {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
|
||||
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
@@ -120,6 +125,17 @@ pub trait SchemeMut {
|
||||
fn fmap(&mut self, id: usize, map: &Map) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn fmap2(&mut self, id: usize, map: &Map2) -> Result<usize> {
|
||||
if map.flags.contains(MapFlags::MAP_FIXED) {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
self.fmap(id, &Map {
|
||||
offset: map.offset,
|
||||
size: map.size,
|
||||
flags: map.flags,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn funmap(&mut self, address: usize) -> Result<usize> {
|
||||
|
||||
Reference in New Issue
Block a user