Unverified Commit b5a0a168 authored by 4lDO2's avatar 4lDO2 🖖
Browse files

Add SYS_FRETURNFD, xopen, and xdup.

parent c4d3a40a
Pipeline #10296 failed with stages
in 1 minute and 8 seconds
......@@ -38,6 +38,7 @@ pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100;
pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118;
pub const SYS_FTRUNCATE: usize = SYS_CLASS_FILE | 93;
pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320;
pub const SYS_FRETURNFD: usize = SYS_CLASS_FILE | 321;
pub const SYS_CHDIR: usize = 12;
pub const SYS_CLOCK_GETTIME: usize = 265;
......
......@@ -15,6 +15,8 @@ sed 's/trait Scheme/trait SchemeBlock/' scheme.rs \
| sed 's/\.map(|o| o as usize)/.map(|o| o.map(|o| o as usize))/' \
| sed 's/Ok(0)/Ok(Some(0))/g' \
| sed 's/Result<\([^>]\+\)>/Result<Option<\1>>/g' \
| sed 's/handle_cross_scheme_link(/handle_cross_scheme_block_link(/g' \
| sed 's/\(OpenResult::SchemeOwned { number }\)/number.map(|number| \1)/g' \
> scheme_block.rs
echo "Generating SchemeBlockMut from SchemeBlock"
......
use core::{slice, str};
use crate::error::{Error, Result, EOPNOTSUPP};
use crate::data::Packet;
use crate::number::SYS_FRETURNFD;
pub use self::scheme::Scheme;
pub use self::scheme_mut::SchemeMut;
pub use self::scheme_block::SchemeBlock;
......@@ -10,6 +14,38 @@ unsafe fn str_from_raw_parts(ptr: *const u8, len: usize) -> Option<&'static str>
let slice = slice::from_raw_parts(ptr, len);
str::from_utf8(slice).ok()
}
fn handle_cross_scheme_inner_link(packet: &mut Packet, res: Result<OpenResult>) -> Result<usize> {
res.map(|r| match r {
OpenResult::SchemeOwned { number } => number,
OpenResult::CrossScheme { fd } => {
let id = core::mem::replace(&mut packet.id, 0);
packet.b = id as usize;
packet.c = fd;
packet.d = 0;
SYS_FRETURNFD
}
})
}
fn handle_cross_scheme_block_link(packet: &Packet, opt: Result<Option<OpenResult>>) -> Result<Option<usize>> {
opt.transpose().map(|res| res.and_then(|o| match o {
OpenResult::SchemeOwned { number } => Ok(number),
// XXX: SchemeBlock's handle() takes a &Packet, so anything except a regular Result<usize>
// is impossible to implement without requiring applications themselves to change. And
// while we would get away with limiting file descriptors to 63 bits, the scheme numbers
// should still be able to use a full 64-bit word. Plus, the schemes which use SchemeBlock
// in general do not need cross-scheme linking.
OpenResult::CrossScheme { .. } => Err(Error::new(EOPNOTSUPP)),
})).transpose()
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OpenResult {
SchemeOwned { number: usize },
CrossScheme { fd: usize },
}
mod scheme;
mod scheme_mut;
......
......@@ -4,13 +4,18 @@ use crate::data::*;
use crate::error::*;
use crate::flag::*;
use crate::number::*;
use crate::scheme::str_from_raw_parts;
use crate::scheme::{OpenResult, str_from_raw_parts};
use super::{handle_cross_scheme_inner_link as handle_cross_scheme_link, handle_cross_scheme_block_link};
pub trait Scheme {
fn handle(&self, packet: &mut Packet) {
#[cfg(target_pointer_width = "32")]
error!("TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field");
let res = match packet.a {
SYS_OPEN => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
self.open(path, packet.d, packet.uid, packet.gid)
handle_cross_scheme_link(packet, self.xopen(path, packet.d, packet.uid, packet.gid))
} else {
Err(Error::new(EINVAL))
},
......@@ -30,7 +35,9 @@ pub trait Scheme {
Err(Error::new(EINVAL))
},
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
SYS_DUP => {
handle_cross_scheme_link(packet, self.xdup(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 as isize, packet.d).map(|o| o as usize),
......@@ -86,6 +93,10 @@ pub trait Scheme {
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn xopen(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<OpenResult> {
self.open(path, flags, uid, gid).map(|number| OpenResult::SchemeOwned { number })
}
#[allow(unused_variables)]
fn chmod(&self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<usize> {
......@@ -108,6 +119,11 @@ pub trait Scheme {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn xdup(&self, old_id: usize, buf: &[u8]) -> Result<OpenResult> {
self.dup(old_id, buf).map(|number| OpenResult::SchemeOwned { number })
}
#[allow(unused_variables)]
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
Err(Error::new(EBADF))
......
......@@ -4,13 +4,18 @@ use crate::data::*;
use crate::error::*;
use crate::flag::*;
use crate::number::*;
use crate::scheme::str_from_raw_parts;
use crate::scheme::{OpenResult, str_from_raw_parts};
use super::{handle_cross_scheme_inner_link as handle_cross_scheme_link, handle_cross_scheme_block_link};
pub trait SchemeBlock {
fn handle(&self, packet: &Packet) -> Option<usize> {
#[cfg(target_pointer_width = "32")]
error!("TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field");
let res = match packet.a {
SYS_OPEN => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
self.open(path, packet.d, packet.uid, packet.gid)
handle_cross_scheme_block_link(packet, self.xopen(path, packet.d, packet.uid, packet.gid))
} else {
Err(Error::new(EINVAL))
},
......@@ -30,7 +35,9 @@ pub trait SchemeBlock {
Err(Error::new(EINVAL))
},
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
SYS_DUP => {
handle_cross_scheme_block_link(packet, self.xdup(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 as isize, packet.d).map(|o| o.map(|o| o as usize)),
......@@ -86,6 +93,10 @@ pub trait SchemeBlock {
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<Option<usize>> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn xopen(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<Option<OpenResult>> {
self.open(path, flags, uid, gid).map(|number| number.map(|number| OpenResult::SchemeOwned { number }))
}
#[allow(unused_variables)]
fn chmod(&self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<Option<usize>> {
......@@ -108,6 +119,11 @@ pub trait SchemeBlock {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn xdup(&self, old_id: usize, buf: &[u8]) -> Result<Option<OpenResult>> {
self.dup(old_id, buf).map(|number| number.map(|number| OpenResult::SchemeOwned { number }))
}
#[allow(unused_variables)]
fn read(&self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
Err(Error::new(EBADF))
......
......@@ -4,13 +4,18 @@ use crate::data::*;
use crate::error::*;
use crate::flag::*;
use crate::number::*;
use crate::scheme::str_from_raw_parts;
use crate::scheme::{OpenResult, str_from_raw_parts};
use super::{handle_cross_scheme_inner_link as handle_cross_scheme_link, handle_cross_scheme_block_link};
pub trait SchemeBlockMut {
fn handle(&mut self, packet: &Packet) -> Option<usize> {
#[cfg(target_pointer_width = "32")]
error!("TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field");
let res = match packet.a {
SYS_OPEN => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
self.open(path, packet.d, packet.uid, packet.gid)
handle_cross_scheme_block_link(packet, self.xopen(path, packet.d, packet.uid, packet.gid))
} else {
Err(Error::new(EINVAL))
},
......@@ -30,7 +35,9 @@ pub trait SchemeBlockMut {
Err(Error::new(EINVAL))
},
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
SYS_DUP => {
handle_cross_scheme_block_link(packet, self.xdup(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 as isize, packet.d).map(|o| o.map(|o| o as usize)),
......@@ -86,6 +93,10 @@ pub trait SchemeBlockMut {
fn open(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<Option<usize>> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn xopen(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<Option<OpenResult>> {
self.open(path, flags, uid, gid).map(|number| number.map(|number| OpenResult::SchemeOwned { number }))
}
#[allow(unused_variables)]
fn chmod(&mut self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<Option<usize>> {
......@@ -108,6 +119,11 @@ pub trait SchemeBlockMut {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn xdup(&mut self, old_id: usize, buf: &[u8]) -> Result<Option<OpenResult>> {
self.dup(old_id, buf).map(|number| number.map(|number| OpenResult::SchemeOwned { number }))
}
#[allow(unused_variables)]
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
Err(Error::new(EBADF))
......
......@@ -4,13 +4,18 @@ use crate::data::*;
use crate::error::*;
use crate::flag::*;
use crate::number::*;
use crate::scheme::str_from_raw_parts;
use crate::scheme::{OpenResult, str_from_raw_parts};
use super::{handle_cross_scheme_inner_link as handle_cross_scheme_link, handle_cross_scheme_block_link};
pub trait SchemeMut {
fn handle(&mut self, packet: &mut Packet) {
#[cfg(target_pointer_width = "32")]
error!("TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field");
let res = match packet.a {
SYS_OPEN => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
self.open(path, packet.d, packet.uid, packet.gid)
handle_cross_scheme_link(packet, self.xopen(path, packet.d, packet.uid, packet.gid))
} else {
Err(Error::new(EINVAL))
},
......@@ -30,7 +35,9 @@ pub trait SchemeMut {
Err(Error::new(EINVAL))
},
SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
SYS_DUP => {
handle_cross_scheme_link(packet, self.xdup(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 as isize, packet.d).map(|o| o as usize),
......@@ -86,6 +93,10 @@ pub trait SchemeMut {
fn open(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn xopen(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<OpenResult> {
self.open(path, flags, uid, gid).map(|number| OpenResult::SchemeOwned { number })
}
#[allow(unused_variables)]
fn chmod(&mut self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<usize> {
......@@ -108,6 +119,11 @@ pub trait SchemeMut {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn xdup(&mut self, old_id: usize, buf: &[u8]) -> Result<OpenResult> {
self.dup(old_id, buf).map(|number| OpenResult::SchemeOwned { number })
}
#[allow(unused_variables)]
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
Err(Error::new(EBADF))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment