Introduce syscall6. Add unlinkat and remove unlink and rmdir.
This commit is contained in:
committed by
Jeremy Soller
parent
d9eae6bb75
commit
e30ed9ab6a
Generated
+3
-2
@@ -208,8 +208,9 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=master#2d346f1d610a358d74cd40360cf7e5dcfc2120d7"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
]
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ bitflags = "2"
|
||||
hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] }
|
||||
linked_list_allocator = "0.9.0"
|
||||
redox-path = "0.2.0"
|
||||
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", branch = "master", default-features = false }
|
||||
redox_syscall = { version = "0.6.0", default-features = false }
|
||||
rmm = { path = "rmm", default-features = false }
|
||||
slab = { version = "0.4", default-features = false }
|
||||
spin = { version = "0.9.8" }
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
exception_stack,
|
||||
memory::{ArchIntCtx, GenericPfFlags},
|
||||
sync::CleanLockToken,
|
||||
syscall::{self, flag::*},
|
||||
syscall,
|
||||
};
|
||||
|
||||
use super::InterruptStack;
|
||||
@@ -189,7 +189,8 @@ exception_stack!(synchronous_exception_at_el0, |stack| {
|
||||
let scratch = &stack.scratch;
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
let ret = syscall::syscall(
|
||||
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, &mut token,
|
||||
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, scratch.x5,
|
||||
&mut token,
|
||||
);
|
||||
stack.scratch.x0 = ret;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,11 @@ impl InterruptStack {
|
||||
pub fn instr_pointer(&self) -> usize {
|
||||
self.iret.elr_el1
|
||||
}
|
||||
pub fn set_arg1(&mut self, arg_opt: Option<usize>) {
|
||||
if let Some(arg) = arg_opt {
|
||||
self.scratch.x1 = arg;
|
||||
}
|
||||
}
|
||||
pub fn dump(&self) {
|
||||
self.iret.dump();
|
||||
self.scratch.dump();
|
||||
|
||||
@@ -161,7 +161,7 @@ unsafe fn handle_user_exception(scause: usize, regs: &mut InterruptStack) {
|
||||
if scause == USERMODE_ECALL {
|
||||
let r = &mut regs.registers;
|
||||
regs.iret.sepc += 4; // skip ecall
|
||||
let ret = syscall::syscall(r.x17, r.x10, r.x11, r.x12, r.x13, r.x14, &mut token);
|
||||
let ret = syscall::syscall(r.x17, r.x10, r.x11, r.x12, r.x13, r.x14, r.x15, &mut token);
|
||||
r.x10 = ret;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,12 @@ impl InterruptStack {
|
||||
self.registers.x10 = ret;
|
||||
}
|
||||
|
||||
pub fn set_arg1(&mut self, arg_opt: Option<usize>) {
|
||||
if let Some(arg) = arg_opt {
|
||||
self.registers.x11 = arg;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dump(&self) {
|
||||
self.iret.dump();
|
||||
self.registers.dump();
|
||||
|
||||
@@ -38,6 +38,7 @@ interrupt_stack!(syscall, |stack| {
|
||||
scratch.edx,
|
||||
preserved.esi,
|
||||
preserved.edi,
|
||||
preserved.ebp,
|
||||
&mut token,
|
||||
);
|
||||
stack.scratch.eax = ret;
|
||||
|
||||
@@ -120,7 +120,11 @@ impl InterruptStack {
|
||||
pub fn set_instr_pointer(&mut self, rip: usize) {
|
||||
self.iret.rip = rip;
|
||||
}
|
||||
|
||||
pub fn set_arg1(&mut self, arg_opt: Option<usize>) {
|
||||
if let Some(arg) = arg_opt {
|
||||
self.scratch.rsi = arg;
|
||||
}
|
||||
}
|
||||
pub fn dump(&self) {
|
||||
self.iret.dump();
|
||||
self.scratch.dump();
|
||||
|
||||
@@ -83,6 +83,7 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack)
|
||||
scratch.rdx,
|
||||
scratch.r10,
|
||||
scratch.r8,
|
||||
scratch.r9,
|
||||
&mut token,
|
||||
);
|
||||
(*stack).scratch.rax = ret;
|
||||
|
||||
@@ -153,14 +153,14 @@ impl super::Context {
|
||||
ptr::write(self.kfx.as_mut_ptr() as *mut FloatRegisters, new);
|
||||
}
|
||||
}
|
||||
pub fn current_syscall(&self) -> Option<[usize; 6]> {
|
||||
pub fn current_syscall(&self) -> Option<[usize; 7]> {
|
||||
if !self.inside_syscall {
|
||||
return None;
|
||||
}
|
||||
let regs = self.regs()?;
|
||||
let scratch = ®s.scratch;
|
||||
Some([
|
||||
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4,
|
||||
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, scratch.x5,
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -88,13 +88,15 @@ impl super::Context {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn current_syscall(&self) -> Option<[usize; 6]> {
|
||||
pub fn current_syscall(&self) -> Option<[usize; 7]> {
|
||||
if !self.inside_syscall {
|
||||
return None;
|
||||
}
|
||||
let regs = self.regs()?;
|
||||
let regs = ®s.registers;
|
||||
Some([regs.x17, regs.x10, regs.x11, regs.x12, regs.x13, regs.x14])
|
||||
Some([
|
||||
regs.x17, regs.x10, regs.x11, regs.x12, regs.x13, regs.x14, regs.x15,
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn write_current_env_regs(&mut self, regs: EnvRegisters) -> Result<()> {
|
||||
|
||||
@@ -145,7 +145,7 @@ impl super::Context {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn current_syscall(&self) -> Option<[usize; 6]> {
|
||||
pub fn current_syscall(&self) -> Option<[usize; 7]> {
|
||||
if !self.inside_syscall {
|
||||
return None;
|
||||
}
|
||||
@@ -157,6 +157,7 @@ impl super::Context {
|
||||
regs.scratch.edx,
|
||||
regs.preserved.esi,
|
||||
regs.preserved.edi,
|
||||
regs.preserved.ebp,
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ impl super::Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn current_syscall(&self) -> Option<[usize; 6]> {
|
||||
pub(crate) fn current_syscall(&self) -> Option<[usize; 7]> {
|
||||
if !self.inside_syscall {
|
||||
return None;
|
||||
}
|
||||
@@ -174,6 +174,7 @@ impl super::Context {
|
||||
scratch.rdx,
|
||||
scratch.r10,
|
||||
scratch.r8,
|
||||
scratch.r9,
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -65,10 +65,10 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
|
||||
if !context.status_reason.is_empty() {
|
||||
println!("reason: {}", context.status_reason);
|
||||
}
|
||||
if let Some([a, b, c, d, e, f]) = context.current_syscall() {
|
||||
if let Some([a, b, c, d, e, f, g]) = context.current_syscall() {
|
||||
println!(
|
||||
"syscall: {}",
|
||||
crate::syscall::debug::format_call(a, b, c, d, e, f)
|
||||
crate::syscall::debug::format_call(a, b, c, d, e, f, g)
|
||||
);
|
||||
}
|
||||
if let Some(ref addr_space) = context.addr_space {
|
||||
|
||||
+5
-2
@@ -57,8 +57,11 @@ fn panic_handler_inner(info: &PanicInfo) -> ! {
|
||||
let context = context_lock.read(token.token());
|
||||
println!("NAME: {}, DEBUG ID: {}", context.name, context.debug_id);
|
||||
|
||||
if let Some([a, b, c, d, e, f]) = context.current_syscall() {
|
||||
println!("SYSCALL: {}", syscall::debug::format_call(a, b, c, d, e, f));
|
||||
if let Some([a, b, c, d, e, f, g]) = context.current_syscall() {
|
||||
println!(
|
||||
"SYSCALL: {}",
|
||||
syscall::debug::format_call(a, b, c, d, e, f, g)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-4
@@ -559,10 +559,14 @@ pub trait KernelScheme: Send + Sync + 'static {
|
||||
) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
fn rmdir(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
fn unlink(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> {
|
||||
fn unlinkat(
|
||||
&self,
|
||||
file: usize,
|
||||
path: &str,
|
||||
flags: usize,
|
||||
ctx: CallerCtx,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<()> {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
fn close(&self, id: usize, token: &mut CleanLockToken) -> Result<()> {
|
||||
@@ -611,6 +615,19 @@ pub struct CallerCtx {
|
||||
pub uid: u32,
|
||||
pub gid: u32,
|
||||
}
|
||||
impl CallerCtx {
|
||||
pub fn filter_uid_gid(self, euid: u32, egid: u32) -> Self {
|
||||
if self.uid == 0 && self.gid == 0 {
|
||||
Self {
|
||||
pid: self.pid,
|
||||
uid: euid,
|
||||
gid: egid,
|
||||
}
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum KernelSchemes {
|
||||
|
||||
+17
-1
@@ -131,6 +131,7 @@ enum ContextHandle {
|
||||
new: Arc<AddrSpaceWrapper>,
|
||||
new_sp: usize,
|
||||
new_ip: usize,
|
||||
arg1: Option<usize>,
|
||||
},
|
||||
|
||||
CurrentFiletable,
|
||||
@@ -444,12 +445,19 @@ impl KernelScheme for ProcScheme {
|
||||
new,
|
||||
new_sp,
|
||||
new_ip,
|
||||
arg1,
|
||||
},
|
||||
} => {
|
||||
let _ = try_stop_context(context, token, |context: &mut Context| {
|
||||
let regs = context.regs_mut().ok_or(Error::new(EBADFD))?;
|
||||
regs.set_instr_pointer(new_ip);
|
||||
regs.set_stack_pointer(new_sp);
|
||||
#[cfg(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "riscv64"
|
||||
))]
|
||||
regs.set_arg1(arg1);
|
||||
|
||||
Ok(context.set_addr_space(Some(new)))
|
||||
})?;
|
||||
@@ -1089,6 +1097,7 @@ impl ContextHandle {
|
||||
let addrspace_fd = iter.next().ok_or(Error::new(EINVAL))??;
|
||||
let sp = iter.next().ok_or(Error::new(EINVAL))??;
|
||||
let ip = iter.next().ok_or(Error::new(EINVAL))??;
|
||||
let arg1 = iter.next().transpose()?;
|
||||
|
||||
let (hopefully_this_scheme, number) = extract_scheme_number(addrspace_fd, token)?;
|
||||
verify_scheme(hopefully_this_scheme)?;
|
||||
@@ -1108,10 +1117,17 @@ impl ContextHandle {
|
||||
new: Arc::clone(addrspace),
|
||||
new_sp: sp,
|
||||
new_ip: ip,
|
||||
arg1,
|
||||
},
|
||||
};
|
||||
|
||||
Ok(3 * mem::size_of::<usize>())
|
||||
let written = if arg1.is_some() {
|
||||
4 * mem::size_of::<usize>()
|
||||
} else {
|
||||
3 * mem::size_of::<usize>()
|
||||
};
|
||||
|
||||
Ok(written)
|
||||
}
|
||||
Self::MmapMinAddr(ref addrspace) => {
|
||||
let val = buf.read_usize()?;
|
||||
|
||||
+32
-6
@@ -81,7 +81,10 @@ impl KernelScheme for RootScheme {
|
||||
let new_close = flags & O_EXLOCK == O_EXLOCK;
|
||||
|
||||
if !v2 {
|
||||
error!("Context {} tried to open a v1 scheme", context::current().read(token.token()).name);
|
||||
error!(
|
||||
"Context {} tried to open a v1 scheme",
|
||||
context::current().read(token.token()).name
|
||||
);
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
if !new_close {
|
||||
@@ -138,21 +141,44 @@ impl KernelScheme for RootScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn unlink(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> {
|
||||
fn unlinkat(
|
||||
&self,
|
||||
fd: usize,
|
||||
path: &str,
|
||||
_flags: usize,
|
||||
ctx: CallerCtx,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<()> {
|
||||
let path = path.trim_matches('/');
|
||||
|
||||
let ens = {
|
||||
let handles = self.handles.read(token.token());
|
||||
let Handle::List { ens } = handles.get(&fd).ok_or(Error::new(ENOENT))? else {
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
*ens
|
||||
};
|
||||
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
{
|
||||
let schemes = scheme::schemes(token.token());
|
||||
if schemes.get_name(ens, path).is_none() {
|
||||
return Err(Error::new(ENODEV));
|
||||
}
|
||||
}
|
||||
|
||||
let inner = {
|
||||
let handles = self.handles.read(token.token());
|
||||
handles
|
||||
.iter()
|
||||
.find_map(|(_id, handle)| {
|
||||
if let Handle::Scheme(inner) = handle {
|
||||
if path == inner.name.as_ref() {
|
||||
return Some(inner.clone());
|
||||
}
|
||||
if let Handle::Scheme(inner) = handle
|
||||
&& path == inner.name.as_ref()
|
||||
{
|
||||
return Some(inner.clone());
|
||||
}
|
||||
None
|
||||
})
|
||||
|
||||
@@ -21,11 +21,11 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
for &(id, ref name, sc) in rows.iter() {
|
||||
let _ = writeln!(string, "{}: {}", id, name);
|
||||
|
||||
if let Some([a, b, c, d, e, f]) = sc {
|
||||
if let Some([a, b, c, d, e, f, g]) = sc {
|
||||
let _ = writeln!(
|
||||
string,
|
||||
" {}",
|
||||
syscall::debug::format_call(a, b, c, d, e, f)
|
||||
syscall::debug::format_call(a, b, c, d, e, f, g)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-15
@@ -1497,24 +1497,19 @@ impl KernelScheme for UserScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn rmdir(&self, path: &str, _ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> {
|
||||
fn unlinkat(
|
||||
&self,
|
||||
file: usize,
|
||||
path: &str,
|
||||
flags: usize,
|
||||
_ctx: CallerCtx,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let mut address = inner.copy_and_capture_tail(path.as_bytes(), token)?;
|
||||
inner.call(
|
||||
Opcode::Rmdir,
|
||||
[address.base(), address.len()],
|
||||
address.span(),
|
||||
token,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unlink(&self, path: &str, _ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let mut address = inner.copy_and_capture_tail(path.as_bytes(), token)?;
|
||||
inner.call(
|
||||
Opcode::Unlink,
|
||||
[address.base(), address.len()],
|
||||
Opcode::UnlinkAt,
|
||||
[file, address.base(), address.len(), flags],
|
||||
address.span(),
|
||||
token,
|
||||
)?;
|
||||
|
||||
+21
-13
@@ -42,20 +42,28 @@ unsafe fn read_struct<T>(ptr: usize) -> Result<T> {
|
||||
}
|
||||
|
||||
//TODO: calling format_call with arguments from another process space will not work
|
||||
pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String {
|
||||
pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize) -> String {
|
||||
match a {
|
||||
SYS_OPEN => format!(
|
||||
"open({:?}, {:#X})",
|
||||
debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())),
|
||||
d
|
||||
),
|
||||
SYS_RMDIR => format!(
|
||||
"rmdir({:?})",
|
||||
debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())),
|
||||
SYS_OPENAT => format!(
|
||||
"openat({} {:?}, {:#0x}, {}, {})",
|
||||
b,
|
||||
debug_path(c, d).as_ref().map(|p| ByteStr(p.as_bytes())),
|
||||
e,
|
||||
f,
|
||||
g
|
||||
),
|
||||
SYS_UNLINK => format!(
|
||||
"unlink({:?})",
|
||||
debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())),
|
||||
SYS_UNLINKAT => format!(
|
||||
"unlinkat({} {:?}, {:#0x}, {}, {})",
|
||||
b,
|
||||
debug_path(c, d).as_ref().map(|p| ByteStr(p.as_bytes())),
|
||||
e,
|
||||
f,
|
||||
g,
|
||||
),
|
||||
SYS_CLOSE => format!("close({})", b),
|
||||
SYS_DUP => format!(
|
||||
@@ -186,8 +194,8 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -
|
||||
),
|
||||
SYS_YIELD => format!("yield()"),
|
||||
_ => format!(
|
||||
"UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})",
|
||||
a, a, b, c, d, e, f
|
||||
"UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X}, {:#X})",
|
||||
a, a, b, c, d, e, f, g
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -219,7 +227,7 @@ impl SyscallDebugInfo {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "syscall_debug", inline)]
|
||||
pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) {
|
||||
pub fn debug_start([a, b, c, d, e, f, g]: [usize; 7], token: &mut CleanLockToken) {
|
||||
if cfg!(not(feature = "syscall_debug")) {
|
||||
return;
|
||||
}
|
||||
@@ -252,7 +260,7 @@ pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) {
|
||||
|
||||
// Do format_call outside print! so possible exception handlers cannot reentrantly
|
||||
// deadlock.
|
||||
let string = format_call(a, b, c, d, e, f);
|
||||
let string = format_call(a, b, c, d, e, f, g);
|
||||
println!("{}", string);
|
||||
|
||||
crate::time::monotonic()
|
||||
@@ -271,7 +279,7 @@ pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) {
|
||||
|
||||
#[cfg_attr(feature = "syscall_debug", inline)]
|
||||
pub fn debug_end(
|
||||
[a, b, c, d, e, f]: [usize; 6],
|
||||
[a, b, c, d, e, f, g]: [usize; 7],
|
||||
result: Result<usize>,
|
||||
token: &mut CleanLockToken,
|
||||
) {
|
||||
@@ -297,7 +305,7 @@ pub fn debug_end(
|
||||
|
||||
// Do format_call outside print! so possible exception handlers cannot reentrantly
|
||||
// deadlock.
|
||||
let string = format_call(a, b, c, d, e, f);
|
||||
let string = format_call(a, b, c, d, e, f, g);
|
||||
print!("{} = ", string);
|
||||
|
||||
match result {
|
||||
|
||||
+36
-47
@@ -1,4 +1,5 @@
|
||||
//! Filesystem syscalls
|
||||
|
||||
use core::{mem::size_of, num::NonZeroUsize};
|
||||
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
@@ -145,6 +146,8 @@ pub fn openat(
|
||||
raw_path: UserSliceRo,
|
||||
flags: usize,
|
||||
fcntl_flags: u32,
|
||||
euid: u32,
|
||||
egid: u32,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<FileHandle> {
|
||||
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
|
||||
@@ -161,7 +164,10 @@ pub fn openat(
|
||||
|
||||
let description = pipe.description.read();
|
||||
|
||||
let caller_ctx = context::current().read(token.token()).caller_ctx();
|
||||
let caller_ctx = context::current()
|
||||
.read(token.token())
|
||||
.caller_ctx()
|
||||
.filter_uid_gid(euid, egid);
|
||||
|
||||
let new_description = {
|
||||
let scheme = scheme::schemes(token.token())
|
||||
@@ -185,7 +191,7 @@ pub fn openat(
|
||||
internal_flags,
|
||||
scheme: description.scheme,
|
||||
number,
|
||||
flags: description.flags,
|
||||
flags: (flags & !O_CLOEXEC) as u32,
|
||||
}))
|
||||
}
|
||||
OpenResult::External(desc) => desc,
|
||||
@@ -196,59 +202,42 @@ pub fn openat(
|
||||
.read(token.token())
|
||||
.add_file(FileDescriptor {
|
||||
description: new_description,
|
||||
cloexec: false,
|
||||
cloexec: flags as usize & O_CLOEXEC == O_CLOEXEC,
|
||||
})
|
||||
.ok_or(Error::new(EMFILE))
|
||||
}
|
||||
/// rmdir syscall
|
||||
pub fn rmdir(raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> {
|
||||
let (scheme_ns, caller_ctx) = {
|
||||
let ctx = context::current();
|
||||
let cx = &ctx.read(token.token());
|
||||
(cx.ens, cx.caller_ctx())
|
||||
};
|
||||
/// Unlinkat syscall
|
||||
pub fn unlinkat(
|
||||
fh: FileHandle,
|
||||
raw_path: UserSliceRo,
|
||||
flags: usize,
|
||||
euid: u32,
|
||||
egid: u32,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<()> {
|
||||
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
|
||||
let pipe = context::current()
|
||||
.read(token.token())
|
||||
.get_file(fh)
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
let description = pipe.description.read();
|
||||
|
||||
let scheme = scheme::schemes(token.token())
|
||||
.get(description.scheme)
|
||||
.ok_or(Error::new(EBADF))?
|
||||
.clone();
|
||||
|
||||
let caller_ctx = context::current()
|
||||
.read(token.token())
|
||||
.caller_ctx()
|
||||
.filter_uid_gid(euid, egid);
|
||||
|
||||
/*
|
||||
let mut path_buf = BorrowedHtBuf::head()?;
|
||||
let path = path_buf.use_for_string(raw_path)?;
|
||||
*/
|
||||
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
|
||||
let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme_name, reference) = path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let scheme = {
|
||||
let schemes = scheme::schemes(token.token());
|
||||
let (_scheme_id, scheme) = schemes
|
||||
.get_name(scheme_ns, scheme_name.as_ref())
|
||||
.ok_or(Error::new(ENODEV))?;
|
||||
scheme.clone()
|
||||
};
|
||||
scheme.rmdir(reference.as_ref(), caller_ctx, token)
|
||||
}
|
||||
|
||||
/// Unlink syscall
|
||||
pub fn unlink(raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> {
|
||||
let (scheme_ns, caller_ctx) = {
|
||||
let ctx = context::current();
|
||||
let cx = &ctx.read(token.token());
|
||||
(cx.ens, cx.caller_ctx())
|
||||
};
|
||||
/*
|
||||
let mut path_buf = BorrowedHtBuf::head()?;
|
||||
let path = path_buf.use_for_string(raw_path)?;
|
||||
*/
|
||||
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
|
||||
let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme_name, reference) = path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let scheme = {
|
||||
let schemes = scheme::schemes(token.token());
|
||||
let (_scheme_id, scheme) = schemes
|
||||
.get_name(scheme_ns, scheme_name.as_ref())
|
||||
.ok_or(Error::new(ENODEV))?;
|
||||
scheme.clone()
|
||||
};
|
||||
scheme.unlink(reference.as_ref(), caller_ctx, token)
|
||||
scheme.unlinkat(description.number, &path_buf, flags, caller_ctx, token)
|
||||
}
|
||||
|
||||
/// Close syscall
|
||||
|
||||
+22
-7
@@ -61,6 +61,7 @@ pub fn syscall(
|
||||
d: usize,
|
||||
e: usize,
|
||||
f: usize,
|
||||
g: usize,
|
||||
token: &mut CleanLockToken,
|
||||
) -> usize {
|
||||
#[inline(always)]
|
||||
@@ -71,6 +72,7 @@ pub fn syscall(
|
||||
d: usize,
|
||||
e: usize,
|
||||
f: usize,
|
||||
g: usize,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
let fd = FileHandle::from(b);
|
||||
@@ -205,11 +207,24 @@ pub fn syscall(
|
||||
UserSlice::ro(f, (e & 0xff) * 8)?,
|
||||
token,
|
||||
),
|
||||
|
||||
SYS_OPEN => open(UserSlice::ro(b, c)?, d, token).map(FileHandle::into),
|
||||
SYS_OPENAT => openat(fd, UserSlice::ro(c, d)?, e, f as _, token).map(FileHandle::into),
|
||||
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?, token).map(|()| 0),
|
||||
SYS_UNLINK => unlink(UserSlice::ro(b, c)?, token).map(|()| 0),
|
||||
SYS_OPENAT => {
|
||||
openat(fd, UserSlice::ro(c, d)?, e, f as _, 0, 0, token).map(FileHandle::into)
|
||||
}
|
||||
SYS_OPENAT_WITH_FILTER => openat(
|
||||
fd,
|
||||
UserSlice::ro(c, d)?,
|
||||
e,
|
||||
(e & syscall::O_FCNTL_MASK) as _,
|
||||
f as _,
|
||||
g as _,
|
||||
token,
|
||||
)
|
||||
.map(FileHandle::into),
|
||||
SYS_UNLINKAT => unlinkat(fd, UserSlice::ro(c, d)?, e, 0, 0, token).map(|()| 0),
|
||||
SYS_UNLINKAT_WITH_FILTER => {
|
||||
unlinkat(fd, UserSlice::ro(c, d)?, e, f as _, g as _, token).map(|()| 0)
|
||||
}
|
||||
SYS_YIELD => sched_yield(token).map(|()| 0),
|
||||
SYS_NANOSLEEP => nanosleep(
|
||||
UserSlice::ro(b, core::mem::size_of::<TimeSpec>())?,
|
||||
@@ -239,11 +254,11 @@ pub fn syscall(
|
||||
|
||||
PercpuBlock::current().inside_syscall.set(true);
|
||||
|
||||
debug_start([a, b, c, d, e, f], token);
|
||||
debug_start([a, b, c, d, e, f, g], token);
|
||||
|
||||
let result = inner(a, b, c, d, e, f, token);
|
||||
let result = inner(a, b, c, d, e, f, g, token);
|
||||
|
||||
debug_end([a, b, c, d, e, f], result, token);
|
||||
debug_end([a, b, c, d, e, f, g], result, token);
|
||||
|
||||
let percpu = PercpuBlock::current();
|
||||
percpu.inside_syscall.set(false);
|
||||
|
||||
Reference in New Issue
Block a user