mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Replace old user space read/write with new APIs
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
7ade2fcb57
commit
75da7fd30e
@ -20,7 +20,6 @@ use crate::{
|
|||||||
signal::{Pollee, Poller},
|
signal::{Pollee, Poller},
|
||||||
JobControl, Terminal,
|
JobControl, Terminal,
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const BUFFER_CAPACITY: usize = 4096;
|
const BUFFER_CAPACITY: usize = 4096;
|
||||||
@ -150,11 +149,11 @@ impl FileIo for PtyMaster {
|
|||||||
match cmd {
|
match cmd {
|
||||||
IoctlCmd::TCGETS => {
|
IoctlCmd::TCGETS => {
|
||||||
let termios = self.output.termios();
|
let termios = self.output.termios();
|
||||||
write_val_to_user(arg, &termios)?;
|
CurrentUserSpace::get().write_val(arg, &termios)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TCSETS => {
|
IoctlCmd::TCSETS => {
|
||||||
let termios = read_val_from_user(arg)?;
|
let termios = CurrentUserSpace::get().read_val(arg)?;
|
||||||
self.output.set_termios(termios);
|
self.output.set_termios(termios);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
@ -164,7 +163,7 @@ impl FileIo for PtyMaster {
|
|||||||
}
|
}
|
||||||
IoctlCmd::TIOCGPTN => {
|
IoctlCmd::TIOCGPTN => {
|
||||||
let idx = self.index();
|
let idx = self.index();
|
||||||
write_val_to_user(arg, &idx)?;
|
CurrentUserSpace::get().write_val(arg, &idx)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCGPTPEER => {
|
IoctlCmd::TIOCGPTPEER => {
|
||||||
@ -197,11 +196,11 @@ impl FileIo for PtyMaster {
|
|||||||
}
|
}
|
||||||
IoctlCmd::TIOCGWINSZ => {
|
IoctlCmd::TIOCGWINSZ => {
|
||||||
let winsize = self.output.window_size();
|
let winsize = self.output.window_size();
|
||||||
write_val_to_user(arg, &winsize)?;
|
CurrentUserSpace::get().write_val(arg, &winsize)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCSWINSZ => {
|
IoctlCmd::TIOCSWINSZ => {
|
||||||
let winsize = read_val_from_user(arg)?;
|
let winsize = CurrentUserSpace::get().read_val(arg)?;
|
||||||
self.output.set_window_size(winsize);
|
self.output.set_window_size(winsize);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
@ -213,12 +212,12 @@ impl FileIo for PtyMaster {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
let fg_pgid = foreground.pgid();
|
let fg_pgid = foreground.pgid();
|
||||||
write_val_to_user(arg, &fg_pgid)?;
|
CurrentUserSpace::get().write_val(arg, &fg_pgid)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCSPGRP => {
|
IoctlCmd::TIOCSPGRP => {
|
||||||
let pgid = {
|
let pgid = {
|
||||||
let pgid: i32 = read_val_from_user(arg)?;
|
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?;
|
||||||
if pgid < 0 {
|
if pgid < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
||||||
}
|
}
|
||||||
@ -238,7 +237,7 @@ impl FileIo for PtyMaster {
|
|||||||
}
|
}
|
||||||
IoctlCmd::FIONREAD => {
|
IoctlCmd::FIONREAD => {
|
||||||
let len = self.input.lock().len() as i32;
|
let len = self.input.lock().len() as i32;
|
||||||
write_val_to_user(arg, &len)?;
|
CurrentUserSpace::get().write_val(arg, &len)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
_ => Ok(0),
|
_ => Ok(0),
|
||||||
@ -372,12 +371,12 @@ impl FileIo for PtySlave {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let fg_pgid = foreground.pgid();
|
let fg_pgid = foreground.pgid();
|
||||||
write_val_to_user(arg, &fg_pgid)?;
|
CurrentUserSpace::get().write_val(arg, &fg_pgid)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCSPGRP => {
|
IoctlCmd::TIOCSPGRP => {
|
||||||
let pgid = {
|
let pgid = {
|
||||||
let pgid: i32 = read_val_from_user(arg)?;
|
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?;
|
||||||
if pgid < 0 {
|
if pgid < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
||||||
}
|
}
|
||||||
@ -397,7 +396,7 @@ impl FileIo for PtySlave {
|
|||||||
}
|
}
|
||||||
IoctlCmd::FIONREAD => {
|
IoctlCmd::FIONREAD => {
|
||||||
let buffer_len = self.master().slave_buf_len() as i32;
|
let buffer_len = self.master().slave_buf_len() as i32;
|
||||||
write_val_to_user(arg, &buffer_len)?;
|
CurrentUserSpace::get().write_val(arg, &buffer_len)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
_ => Ok(0),
|
_ => Ok(0),
|
||||||
|
@ -8,8 +8,8 @@ use crate::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
events::IoEvents,
|
events::IoEvents,
|
||||||
fs::{inode_handle::FileIo, utils::IoctlCmd},
|
fs::{inode_handle::FileIo, utils::IoctlCmd},
|
||||||
|
prelude::*,
|
||||||
process::signal::Poller,
|
process::signal::Poller,
|
||||||
util::{read_val_from_user, write_bytes_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const TDX_REPORTDATA_LEN: usize = 64;
|
const TDX_REPORTDATA_LEN: usize = 64;
|
||||||
@ -83,7 +83,8 @@ impl FileIo for TdxGuest {
|
|||||||
fn handle_get_report(arg: usize) -> Result<i32> {
|
fn handle_get_report(arg: usize) -> Result<i32> {
|
||||||
const SHARED_BIT: u8 = 51;
|
const SHARED_BIT: u8 = 51;
|
||||||
const SHARED_MASK: u64 = 1u64 << SHARED_BIT;
|
const SHARED_MASK: u64 = 1u64 << SHARED_BIT;
|
||||||
let user_request: TdxReportRequest = read_val_from_user(arg)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let user_request: TdxReportRequest = user_space.read_val(arg)?;
|
||||||
|
|
||||||
let vm_segment = FrameAllocOptions::new(2)
|
let vm_segment = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
@ -112,6 +113,6 @@ fn handle_get_report(arg: usize) -> Result<i32> {
|
|||||||
.read_bytes(1024, &mut generated_report)
|
.read_bytes(1024, &mut generated_report)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let report_slice: &[u8] = &generated_report;
|
let report_slice: &[u8] = &generated_report;
|
||||||
write_bytes_to_user(tdx_report_vaddr, &mut VmReader::from(report_slice))?;
|
user_space.write_bytes(tdx_report_vaddr, &mut VmReader::from(report_slice))?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ use crate::{
|
|||||||
signal::{signals::kernel::KernelSignal, Poller},
|
signal::{signals::kernel::KernelSignal, Poller},
|
||||||
JobControl, Process, Terminal,
|
JobControl, Process, Terminal,
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod device;
|
mod device;
|
||||||
@ -97,7 +96,7 @@ impl FileIo for Tty {
|
|||||||
// Get terminal attributes
|
// Get terminal attributes
|
||||||
let termios = self.ldisc.termios();
|
let termios = self.ldisc.termios();
|
||||||
trace!("get termios = {:?}", termios);
|
trace!("get termios = {:?}", termios);
|
||||||
write_val_to_user(arg, &termios)?;
|
CurrentUserSpace::get().write_val(arg, &termios)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCGPGRP => {
|
IoctlCmd::TIOCGPGRP => {
|
||||||
@ -106,13 +105,13 @@ impl FileIo for Tty {
|
|||||||
};
|
};
|
||||||
let fg_pgid = foreground.pgid();
|
let fg_pgid = foreground.pgid();
|
||||||
debug!("fg_pgid = {}", fg_pgid);
|
debug!("fg_pgid = {}", fg_pgid);
|
||||||
write_val_to_user(arg, &fg_pgid)?;
|
CurrentUserSpace::get().write_val(arg, &fg_pgid)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCSPGRP => {
|
IoctlCmd::TIOCSPGRP => {
|
||||||
// Set the process group id of fg progress group
|
// Set the process group id of fg progress group
|
||||||
let pgid = {
|
let pgid = {
|
||||||
let pgid: i32 = read_val_from_user(arg)?;
|
let pgid: i32 = CurrentUserSpace::get().read_val(arg)?;
|
||||||
if pgid < 0 {
|
if pgid < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
return_errno_with_message!(Errno::EINVAL, "negative pgid");
|
||||||
}
|
}
|
||||||
@ -127,20 +126,20 @@ impl FileIo for Tty {
|
|||||||
}
|
}
|
||||||
IoctlCmd::TCSETS => {
|
IoctlCmd::TCSETS => {
|
||||||
// Set terminal attributes
|
// Set terminal attributes
|
||||||
let termios = read_val_from_user(arg)?;
|
let termios = CurrentUserSpace::get().read_val(arg)?;
|
||||||
debug!("set termios = {:?}", termios);
|
debug!("set termios = {:?}", termios);
|
||||||
self.ldisc.set_termios(termios);
|
self.ldisc.set_termios(termios);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TCSETSW => {
|
IoctlCmd::TCSETSW => {
|
||||||
let termios = read_val_from_user(arg)?;
|
let termios = CurrentUserSpace::get().read_val(arg)?;
|
||||||
debug!("set termios = {:?}", termios);
|
debug!("set termios = {:?}", termios);
|
||||||
self.ldisc.set_termios(termios);
|
self.ldisc.set_termios(termios);
|
||||||
// TODO: drain output buffer
|
// TODO: drain output buffer
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TCSETSF => {
|
IoctlCmd::TCSETSF => {
|
||||||
let termios = read_val_from_user(arg)?;
|
let termios = CurrentUserSpace::get().read_val(arg)?;
|
||||||
debug!("set termios = {:?}", termios);
|
debug!("set termios = {:?}", termios);
|
||||||
self.ldisc.set_termios(termios);
|
self.ldisc.set_termios(termios);
|
||||||
self.ldisc.drain_input();
|
self.ldisc.drain_input();
|
||||||
@ -149,11 +148,11 @@ impl FileIo for Tty {
|
|||||||
}
|
}
|
||||||
IoctlCmd::TIOCGWINSZ => {
|
IoctlCmd::TIOCGWINSZ => {
|
||||||
let winsize = self.ldisc.window_size();
|
let winsize = self.ldisc.window_size();
|
||||||
write_val_to_user(arg, &winsize)?;
|
CurrentUserSpace::get().write_val(arg, &winsize)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCSWINSZ => {
|
IoctlCmd::TIOCSWINSZ => {
|
||||||
let winsize = read_val_from_user(arg)?;
|
let winsize = CurrentUserSpace::get().read_val(arg)?;
|
||||||
self.ldisc.set_window_size(winsize);
|
self.ldisc.set_window_size(winsize);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ pub(crate) use crate::{
|
|||||||
error::{Errno, Error},
|
error::{Errno, Error},
|
||||||
print, println,
|
print, println,
|
||||||
time::{wait::WaitTimeout, Clock},
|
time::{wait::WaitTimeout, Clock},
|
||||||
|
util::{CurrentUserSpace, ReadCString},
|
||||||
};
|
};
|
||||||
pub(crate) type Result<T> = core::result::Result<T, Error>;
|
pub(crate) type Result<T> = core::result::Result<T, Error>;
|
||||||
pub(crate) use crate::{return_errno, return_errno_with_message};
|
pub(crate) use crate::{return_errno, return_errno_with_message};
|
||||||
|
@ -5,7 +5,6 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
process::{do_exit_group, TermStatus},
|
process::{do_exit_group, TermStatus},
|
||||||
thread::{thread_table, Thread, Tid},
|
thread::{thread_table, Thread, Tid},
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Exits the thread if the thread is a POSIX thread.
|
/// Exits the thread if the thread is a POSIX thread.
|
||||||
@ -28,7 +27,9 @@ pub fn do_exit(thread: Arc<Thread>, term_status: TermStatus) -> Result<()> {
|
|||||||
if *clear_ctid != 0 {
|
if *clear_ctid != 0 {
|
||||||
futex_wake(*clear_ctid, 1)?;
|
futex_wake(*clear_ctid, 1)?;
|
||||||
// FIXME: the correct write length?
|
// FIXME: the correct write length?
|
||||||
write_val_to_user(*clear_ctid, &0u32).unwrap();
|
CurrentUserSpace::get()
|
||||||
|
.write_val(*clear_ctid, &0u32)
|
||||||
|
.unwrap();
|
||||||
*clear_ctid = 0;
|
*clear_ctid = 0;
|
||||||
}
|
}
|
||||||
// exit the robust list: walk the robust list; mark futex words as dead and do futex wake
|
// exit the robust list: walk the robust list; mark futex words as dead and do futex wake
|
||||||
|
@ -9,7 +9,7 @@ use ostd::{
|
|||||||
};
|
};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
use crate::{prelude::*, util::read_val_from_user};
|
use crate::prelude::*;
|
||||||
|
|
||||||
type FutexBitSet = u32;
|
type FutexBitSet = u32;
|
||||||
type FutexBucketRef = Arc<Mutex<FutexBucket>>;
|
type FutexBucketRef = Arc<Mutex<FutexBucket>>;
|
||||||
@ -330,7 +330,7 @@ impl FutexKey {
|
|||||||
pub fn load_val(&self) -> i32 {
|
pub fn load_val(&self) -> i32 {
|
||||||
// FIXME: how to implement a atomic load?
|
// FIXME: how to implement a atomic load?
|
||||||
warn!("implement an atomic load");
|
warn!("implement an atomic load");
|
||||||
read_val_from_user(self.addr).unwrap()
|
CurrentUserSpace::get().read_val(self.addr).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addr(&self) -> Vaddr {
|
pub fn addr(&self) -> Vaddr {
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{posix_thread::futex::futex_wake, Pid},
|
process::{posix_thread::futex::futex_wake, Pid},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -105,7 +104,8 @@ impl<'a> Iterator for FutexIter<'a> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let Ok(robust_list) = read_val_from_user::<RobustList>(self.entry_ptr) else {
|
let Ok(robust_list) = CurrentUserSpace::get().read_val::<RobustList>(self.entry_ptr)
|
||||||
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
self.entry_ptr = robust_list.next;
|
self.entry_ptr = robust_list.next;
|
||||||
@ -126,11 +126,12 @@ const FUTEX_TID_MASK: u32 = 0x3FFF_FFFF;
|
|||||||
/// Wakeup one robust futex owned by the thread
|
/// Wakeup one robust futex owned by the thread
|
||||||
/// FIXME: requires atomic operations here
|
/// FIXME: requires atomic operations here
|
||||||
pub fn wake_robust_futex(futex_addr: Vaddr, tid: Pid) -> Result<()> {
|
pub fn wake_robust_futex(futex_addr: Vaddr, tid: Pid) -> Result<()> {
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let futex_val = {
|
let futex_val = {
|
||||||
if futex_addr == 0 {
|
if futex_addr == 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "invalid futext addr");
|
return_errno_with_message!(Errno::EINVAL, "invalid futext addr");
|
||||||
}
|
}
|
||||||
read_val_from_user::<u32>(futex_addr)?
|
user_space.read_val::<u32>(futex_addr)?
|
||||||
};
|
};
|
||||||
let mut old_val = futex_val;
|
let mut old_val = futex_val;
|
||||||
loop {
|
loop {
|
||||||
@ -139,11 +140,11 @@ pub fn wake_robust_futex(futex_addr: Vaddr, tid: Pid) -> Result<()> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let new_val = (old_val & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
|
let new_val = (old_val & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
|
||||||
let cur_val = read_val_from_user(futex_addr)?;
|
let cur_val = user_space.read_val(futex_addr)?;
|
||||||
if cur_val != new_val {
|
if cur_val != new_val {
|
||||||
// The futex value has changed, let's retry with current value
|
// The futex value has changed, let's retry with current value
|
||||||
old_val = cur_val;
|
old_val = cur_val;
|
||||||
write_val_to_user(futex_addr, &new_val)?;
|
user_space.write_val(futex_addr, &new_val)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Wakeup one waiter
|
// Wakeup one waiter
|
||||||
|
@ -31,7 +31,6 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
process::{do_exit_group, TermStatus},
|
process::{do_exit_group, TermStatus},
|
||||||
thread::{status::ThreadStatus, Thread},
|
thread::{status::ThreadStatus, Thread},
|
||||||
util::{write_bytes_to_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait SignalContext {
|
pub trait SignalContext {
|
||||||
@ -173,9 +172,10 @@ pub fn handle_user_signal(
|
|||||||
// To avoid corrupting signal stack, we minus 128 first.
|
// To avoid corrupting signal stack, we minus 128 first.
|
||||||
stack_pointer -= 128;
|
stack_pointer -= 128;
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
// 1. write siginfo_t
|
// 1. write siginfo_t
|
||||||
stack_pointer -= mem::size_of::<siginfo_t>() as u64;
|
stack_pointer -= mem::size_of::<siginfo_t>() as u64;
|
||||||
write_val_to_user(stack_pointer as _, &sig_info)?;
|
user_space.write_val(stack_pointer as _, &sig_info)?;
|
||||||
let siginfo_addr = stack_pointer;
|
let siginfo_addr = stack_pointer;
|
||||||
|
|
||||||
// 2. write ucontext_t.
|
// 2. write ucontext_t.
|
||||||
@ -196,7 +196,7 @@ pub fn handle_user_signal(
|
|||||||
ucontext.uc_link = 0;
|
ucontext.uc_link = 0;
|
||||||
}
|
}
|
||||||
// TODO: store fp regs in ucontext
|
// TODO: store fp regs in ucontext
|
||||||
write_val_to_user(stack_pointer as _, &ucontext)?;
|
user_space.write_val(stack_pointer as _, &ucontext)?;
|
||||||
let ucontext_addr = stack_pointer;
|
let ucontext_addr = stack_pointer;
|
||||||
// Store the ucontext addr in sig context of current thread.
|
// Store the ucontext addr in sig context of current thread.
|
||||||
*sig_context = Some(ucontext_addr as Vaddr);
|
*sig_context = Some(ucontext_addr as Vaddr);
|
||||||
@ -217,7 +217,7 @@ pub fn handle_user_signal(
|
|||||||
];
|
];
|
||||||
stack_pointer -= TRAMPOLINE.len() as u64;
|
stack_pointer -= TRAMPOLINE.len() as u64;
|
||||||
let trampoline_rip = stack_pointer;
|
let trampoline_rip = stack_pointer;
|
||||||
write_bytes_to_user(stack_pointer as Vaddr, &mut VmReader::from(TRAMPOLINE))?;
|
user_space.write_bytes(stack_pointer as Vaddr, &mut VmReader::from(TRAMPOLINE))?;
|
||||||
stack_pointer = write_u64_to_user_stack(stack_pointer, trampoline_rip)?;
|
stack_pointer = write_u64_to_user_stack(stack_pointer, trampoline_rip)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ fn use_alternate_signal_stack(posix_thread: &PosixThread) -> Option<usize> {
|
|||||||
|
|
||||||
fn write_u64_to_user_stack(rsp: u64, value: u64) -> Result<u64> {
|
fn write_u64_to_user_stack(rsp: u64, value: u64) -> Result<u64> {
|
||||||
let rsp = rsp - 8;
|
let rsp = rsp - 8;
|
||||||
write_val_to_user(rsp as Vaddr, &value)?;
|
CurrentUserSpace::get().write_val(rsp as Vaddr, &value)?;
|
||||||
Ok(rsp)
|
Ok(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
utils::PATH_MAX,
|
utils::PATH_MAX,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
||||||
@ -55,7 +54,7 @@ pub fn do_faccessat(
|
|||||||
let flags = FaccessatFlags::from_bits(flags)
|
let flags = FaccessatFlags::from_bits(flags)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid flags"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid flags"))?;
|
||||||
|
|
||||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!(
|
debug!(
|
||||||
"dirfd = {}, path = {:?}, mode = {:o}, flags = {:?}",
|
"dirfd = {}, path = {:?}, mode = {:o}, flags = {:?}",
|
||||||
dirfd, path, mode, flags
|
dirfd, path, mode, flags
|
||||||
|
@ -7,12 +7,12 @@ use crate::{
|
|||||||
credentials,
|
credentials,
|
||||||
credentials::c_types::{cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3},
|
credentials::c_types::{cap_user_data_t, cap_user_header_t, LINUX_CAPABILITY_VERSION_3},
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_capget(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_capget(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let cap_user_header: cap_user_header_t =
|
let cap_user_header: cap_user_header_t =
|
||||||
read_val_from_user::<cap_user_header_t>(cap_user_header_addr)?;
|
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
||||||
|
|
||||||
if cap_user_header.version != LINUX_CAPABILITY_VERSION_3 {
|
if cap_user_header.version != LINUX_CAPABILITY_VERSION_3 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "not supported (capability version is not 3)");
|
return_errno_with_message!(Errno::EINVAL, "not supported (capability version is not 3)");
|
||||||
@ -42,6 +42,6 @@ pub fn sys_capget(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Res
|
|||||||
inheritable: inheritable_capset.as_u32(),
|
inheritable: inheritable_capset.as_u32(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(cap_user_data_addr, &result)?;
|
user_space.write_val(cap_user_data_addr, &result)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
credentials_mut,
|
credentials_mut,
|
||||||
},
|
},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn make_kernel_cap(low: u32, high: u32) -> u64 {
|
fn make_kernel_cap(low: u32, high: u32) -> u64 {
|
||||||
@ -18,8 +17,9 @@ fn make_kernel_cap(low: u32, high: u32) -> u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_capset(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_capset(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let cap_user_header: cap_user_header_t =
|
let cap_user_header: cap_user_header_t =
|
||||||
read_val_from_user::<cap_user_header_t>(cap_user_header_addr)?;
|
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
||||||
|
|
||||||
if cap_user_header.version != LINUX_CAPABILITY_VERSION_3 {
|
if cap_user_header.version != LINUX_CAPABILITY_VERSION_3 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "not supported (capability version is not 3)");
|
return_errno_with_message!(Errno::EINVAL, "not supported (capability version is not 3)");
|
||||||
@ -33,7 +33,8 @@ pub fn sys_capset(cap_user_header_addr: Vaddr, cap_user_data_addr: Vaddr) -> Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert the cap(u32) to u64
|
// Convert the cap(u32) to u64
|
||||||
let cap_user_data: cap_user_data_t = read_val_from_user::<cap_user_data_t>(cap_user_data_addr)?;
|
let cap_user_data: cap_user_data_t =
|
||||||
|
user_space.read_val::<cap_user_data_t>(cap_user_data_addr)?;
|
||||||
let inheritable = make_kernel_cap(cap_user_data.inheritable, 0);
|
let inheritable = make_kernel_cap(cap_user_data.inheritable, 0);
|
||||||
let permitted = make_kernel_cap(cap_user_data.permitted, 0);
|
let permitted = make_kernel_cap(cap_user_data.permitted, 0);
|
||||||
let effective = make_kernel_cap(cap_user_data.effective, 0);
|
let effective = make_kernel_cap(cap_user_data.effective, 0);
|
||||||
|
@ -5,11 +5,10 @@ use crate::{
|
|||||||
fs::{file_table::FileDesc, fs_resolver::FsPath, inode_handle::InodeHandle, utils::InodeType},
|
fs::{file_table::FileDesc, fs_resolver::FsPath, inode_handle::InodeHandle, utils::InodeType},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chdir(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_chdir(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
utils::{InodeMode, PATH_MAX},
|
utils::{InodeMode, PATH_MAX},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result<SyscallReturn> {
|
||||||
@ -32,7 +31,7 @@ pub fn sys_fchmodat(
|
|||||||
mode: u16,
|
mode: u16,
|
||||||
/* flags: u32, */
|
/* flags: u32, */
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,);
|
debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{Gid, Uid},
|
process::{Gid, Uid},
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
||||||
@ -54,7 +53,7 @@ pub fn sys_fchownat(
|
|||||||
gid: i32,
|
gid: i32,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
let flags = ChownFlags::from_bits(flags)
|
let flags = ChownFlags::from_bits(flags)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -5,11 +5,10 @@ use crate::{
|
|||||||
fs::{fs_resolver::FsPath, utils::InodeType},
|
fs::{fs_resolver::FsPath, utils::InodeType},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chroot(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_chroot(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -18,7 +18,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
timespec_t, Clock,
|
timespec_t, Clock,
|
||||||
},
|
},
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_clock_gettime(clockid: clockid_t, timespec_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_clock_gettime(clockid: clockid_t, timespec_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -27,7 +26,7 @@ pub fn sys_clock_gettime(clockid: clockid_t, timespec_addr: Vaddr) -> Result<Sys
|
|||||||
let time_duration = read_clock(clockid)?;
|
let time_duration = read_clock(clockid)?;
|
||||||
|
|
||||||
let timespec = timespec_t::from(time_duration);
|
let timespec = timespec_t::from(time_duration);
|
||||||
write_val_to_user(timespec_addr, ×pec)?;
|
CurrentUserSpace::get().write_val(timespec_addr, ×pec)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{clone_child, signal::constants::SIGCHLD, CloneArgs, CloneFlags},
|
process::{clone_child, signal::constants::SIGCHLD, CloneArgs, CloneFlags},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The order of arguments for clone differs in different architecture.
|
// The order of arguments for clone differs in different architecture.
|
||||||
@ -41,7 +40,7 @@ pub fn sys_clone3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let clone_args = {
|
let clone_args = {
|
||||||
let args: Clone3Args = read_val_from_user(clong_args_addr)?;
|
let args: Clone3Args = CurrentUserSpace::get().read_val(clong_args_addr)?;
|
||||||
trace!("clone3 args = {:x?}", args);
|
trace!("clone3 args = {:x?}", args);
|
||||||
CloneArgs::from(args)
|
CloneArgs::from(args)
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_epoll_create(size: i32) -> Result<SyscallReturn> {
|
pub fn sys_epoll_create(size: i32) -> Result<SyscallReturn> {
|
||||||
@ -62,14 +61,14 @@ pub fn sys_epoll_ctl(
|
|||||||
|
|
||||||
let cmd = match op {
|
let cmd = match op {
|
||||||
EPOLL_CTL_ADD => {
|
EPOLL_CTL_ADD => {
|
||||||
let c_epoll_event = read_val_from_user::<c_epoll_event>(event_addr)?;
|
let c_epoll_event = CurrentUserSpace::get().read_val::<c_epoll_event>(event_addr)?;
|
||||||
let event = EpollEvent::from(&c_epoll_event);
|
let event = EpollEvent::from(&c_epoll_event);
|
||||||
let flags = EpollFlags::from_bits_truncate(c_epoll_event.events);
|
let flags = EpollFlags::from_bits_truncate(c_epoll_event.events);
|
||||||
EpollCtl::Add(fd, event, flags)
|
EpollCtl::Add(fd, event, flags)
|
||||||
}
|
}
|
||||||
EPOLL_CTL_DEL => EpollCtl::Del(fd),
|
EPOLL_CTL_DEL => EpollCtl::Del(fd),
|
||||||
EPOLL_CTL_MOD => {
|
EPOLL_CTL_MOD => {
|
||||||
let c_epoll_event = read_val_from_user::<c_epoll_event>(event_addr)?;
|
let c_epoll_event = CurrentUserSpace::get().read_val::<c_epoll_event>(event_addr)?;
|
||||||
let event = EpollEvent::from(&c_epoll_event);
|
let event = EpollEvent::from(&c_epoll_event);
|
||||||
let flags = EpollFlags::from_bits_truncate(c_epoll_event.events);
|
let flags = EpollFlags::from_bits_truncate(c_epoll_event.events);
|
||||||
EpollCtl::Mod(fd, event, flags)
|
EpollCtl::Mod(fd, event, flags)
|
||||||
@ -139,9 +138,10 @@ pub fn sys_epoll_wait(
|
|||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
let mut write_addr = events_addr;
|
let mut write_addr = events_addr;
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
for epoll_event in epoll_events.iter() {
|
for epoll_event in epoll_events.iter() {
|
||||||
let c_epoll_event = c_epoll_event::from(epoll_event);
|
let c_epoll_event = c_epoll_event::from(epoll_event);
|
||||||
write_val_to_user(write_addr, &c_epoll_event)?;
|
user_space.write_val(write_addr, &c_epoll_event)?;
|
||||||
write_addr += core::mem::size_of::<c_epoll_event>();
|
write_addr += core::mem::size_of::<c_epoll_event>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ pub fn sys_epoll_wait(
|
|||||||
|
|
||||||
fn set_signal_mask(set_ptr: Vaddr) -> Result<SigMask> {
|
fn set_signal_mask(set_ptr: Vaddr) -> Result<SigMask> {
|
||||||
let new_mask: Option<SigMask> = if set_ptr != 0 {
|
let new_mask: Option<SigMask> = if set_ptr != 0 {
|
||||||
Some(read_val_from_user::<u64>(set_ptr)?.into())
|
Some(CurrentUserSpace::get().read_val::<u64>(set_ptr)?.into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -208,9 +208,10 @@ pub fn sys_epoll_pwait(
|
|||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
let mut write_addr = events_addr;
|
let mut write_addr = events_addr;
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
for event in ready_events.iter() {
|
for event in ready_events.iter() {
|
||||||
let c_event = c_epoll_event::from(event);
|
let c_event = c_epoll_event::from(event);
|
||||||
write_val_to_user(write_addr, &c_event)?;
|
user_space.write_val(write_addr, &c_event)?;
|
||||||
write_addr += core::mem::size_of::<c_epoll_event>();
|
write_addr += core::mem::size_of::<c_epoll_event>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ use crate::{
|
|||||||
posix_thread::{PosixThreadExt, ThreadName},
|
posix_thread::{PosixThreadExt, ThreadName},
|
||||||
Credentials, Process, MAX_ARGV_NUMBER, MAX_ARG_LEN, MAX_ENVP_NUMBER, MAX_ENV_LEN,
|
Credentials, Process, MAX_ARGV_NUMBER, MAX_ARG_LEN, MAX_ENVP_NUMBER, MAX_ENV_LEN,
|
||||||
},
|
},
|
||||||
util::{read_cstring_from_user, read_val_from_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_execve(
|
pub fn sys_execve(
|
||||||
@ -149,7 +148,7 @@ bitflags::bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_filename(filename_ptr: Vaddr) -> Result<String> {
|
fn read_filename(filename_ptr: Vaddr) -> Result<String> {
|
||||||
let filename = read_cstring_from_user(filename_ptr, MAX_FILENAME_LEN)?;
|
let filename = CurrentUserSpace::get().read_cstring(filename_ptr, MAX_FILENAME_LEN)?;
|
||||||
Ok(filename.into_string().unwrap())
|
Ok(filename.into_string().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,15 +164,16 @@ fn read_cstring_vec(
|
|||||||
}
|
}
|
||||||
let mut read_addr = array_ptr;
|
let mut read_addr = array_ptr;
|
||||||
let mut find_null = false;
|
let mut find_null = false;
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
for _ in 0..max_string_number {
|
for _ in 0..max_string_number {
|
||||||
let cstring_ptr = read_val_from_user::<usize>(read_addr)?;
|
let cstring_ptr = user_space.read_val::<usize>(read_addr)?;
|
||||||
read_addr += 8;
|
read_addr += 8;
|
||||||
// read a null pointer
|
// read a null pointer
|
||||||
if cstring_ptr == 0 {
|
if cstring_ptr == 0 {
|
||||||
find_null = true;
|
find_null = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let cstring = read_cstring_from_user(cstring_ptr, max_string_len)?;
|
let cstring = user_space.read_cstring(cstring_ptr, max_string_len)?;
|
||||||
res.push(cstring);
|
res.push(cstring);
|
||||||
}
|
}
|
||||||
if !find_null {
|
if !find_null {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, util::write_bytes_to_user};
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getcwd(buf: Vaddr, len: usize) -> Result<SyscallReturn> {
|
pub fn sys_getcwd(buf: Vaddr, len: usize) -> Result<SyscallReturn> {
|
||||||
// TODO: getcwd only return a fake result now
|
// TODO: getcwd only return a fake result now
|
||||||
let fake_cwd = CString::new("/")?;
|
let fake_cwd = CString::new("/")?;
|
||||||
let bytes = fake_cwd.as_bytes_with_nul();
|
let bytes = fake_cwd.as_bytes_with_nul();
|
||||||
let write_len = len.min(bytes.len());
|
let write_len = len.min(bytes.len());
|
||||||
write_bytes_to_user(buf, &mut VmReader::from(&bytes[..write_len]))?;
|
CurrentUserSpace::get().write_bytes(buf, &mut VmReader::from(&bytes[..write_len]))?;
|
||||||
Ok(SyscallReturn::Return(write_len as _))
|
Ok(SyscallReturn::Return(write_len as _))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
utils::{DirentVisitor, InodeType},
|
utils::{DirentVisitor, InodeType},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::write_bytes_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<SyscallReturn> {
|
pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<SyscallReturn> {
|
||||||
@ -36,7 +35,7 @@ pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<Sys
|
|||||||
let mut reader = DirentBufferReader::<Dirent>::new(&mut buffer); // Use the non-64-bit reader
|
let mut reader = DirentBufferReader::<Dirent>::new(&mut buffer); // Use the non-64-bit reader
|
||||||
let _ = inode_handle.readdir(&mut reader)?;
|
let _ = inode_handle.readdir(&mut reader)?;
|
||||||
let read_len = reader.read_len();
|
let read_len = reader.read_len();
|
||||||
write_bytes_to_user(buf_addr, &mut VmReader::from(&buffer[..read_len]))?;
|
CurrentUserSpace::get().write_bytes(buf_addr, &mut VmReader::from(&buffer[..read_len]))?;
|
||||||
Ok(SyscallReturn::Return(read_len as _))
|
Ok(SyscallReturn::Return(read_len as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ pub fn sys_getdents64(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<S
|
|||||||
let mut reader = DirentBufferReader::<Dirent64>::new(&mut buffer);
|
let mut reader = DirentBufferReader::<Dirent64>::new(&mut buffer);
|
||||||
let _ = inode_handle.readdir(&mut reader)?;
|
let _ = inode_handle.readdir(&mut reader)?;
|
||||||
let read_len = reader.read_len();
|
let read_len = reader.read_len();
|
||||||
write_bytes_to_user(buf_addr, &mut VmReader::from(&buffer[..read_len]))?;
|
CurrentUserSpace::get().write_bytes(buf_addr, &mut VmReader::from(&buffer[..read_len]))?;
|
||||||
Ok(SyscallReturn::Return(read_len as _))
|
Ok(SyscallReturn::Return(read_len as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials, util::write_val_to_user};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getgroups(size: i32, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getgroups(size: i32, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
|
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
|
||||||
@ -24,9 +24,10 @@ pub fn sys_getgroups(size: i32, group_list_addr: Vaddr) -> Result<SyscallReturn>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
for (idx, gid) in groups.iter().enumerate() {
|
for (idx, gid) in groups.iter().enumerate() {
|
||||||
let addr = group_list_addr + idx * core::mem::size_of_val(gid);
|
let addr = group_list_addr + idx * core::mem::size_of_val(gid);
|
||||||
write_val_to_user(addr, gid)?;
|
user_space.write_val(addr, gid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(groups.len() as _))
|
Ok(SyscallReturn::Return(groups.len() as _))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{device, prelude::*, util::write_bytes_to_user};
|
use crate::{device, prelude::*};
|
||||||
|
|
||||||
pub fn sys_getrandom(buf: Vaddr, count: usize, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_getrandom(buf: Vaddr, count: usize, flags: u32) -> Result<SyscallReturn> {
|
||||||
let flags = GetRandomFlags::from_bits_truncate(flags);
|
let flags = GetRandomFlags::from_bits_truncate(flags);
|
||||||
@ -17,7 +17,7 @@ pub fn sys_getrandom(buf: Vaddr, count: usize, flags: u32) -> Result<SyscallRetu
|
|||||||
} else {
|
} else {
|
||||||
device::Urandom::getrandom(&mut buffer)?
|
device::Urandom::getrandom(&mut buffer)?
|
||||||
};
|
};
|
||||||
write_bytes_to_user(buf, &mut VmReader::from(buffer.as_slice()))?;
|
CurrentUserSpace::get().write_bytes(buf, &mut VmReader::from(buffer.as_slice()))?;
|
||||||
Ok(SyscallReturn::Return(read_len as isize))
|
Ok(SyscallReturn::Return(read_len as isize))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials, util::write_val_to_user};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getresgid(rgid_ptr: Vaddr, egid_ptr: Vaddr, sgid_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getresgid(rgid_ptr: Vaddr, egid_ptr: Vaddr, sgid_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("rgid_ptr = 0x{rgid_ptr:x}, egid_ptr = 0x{egid_ptr:x}, sgid_ptr = 0x{sgid_ptr:x}");
|
debug!("rgid_ptr = 0x{rgid_ptr:x}, egid_ptr = 0x{egid_ptr:x}, sgid_ptr = 0x{sgid_ptr:x}");
|
||||||
|
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
|
|
||||||
let rgid = credentials.rgid();
|
let rgid = credentials.rgid();
|
||||||
write_val_to_user(rgid_ptr, &rgid)?;
|
user_space.write_val(rgid_ptr, &rgid)?;
|
||||||
|
|
||||||
let egid = credentials.egid();
|
let egid = credentials.egid();
|
||||||
write_val_to_user(egid_ptr, &egid)?;
|
user_space.write_val(egid_ptr, &egid)?;
|
||||||
|
|
||||||
let sgid = credentials.sgid();
|
let sgid = credentials.sgid();
|
||||||
write_val_to_user(sgid_ptr, &sgid)?;
|
user_space.write_val(sgid_ptr, &sgid)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials, util::write_val_to_user};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getresuid(ruid_ptr: Vaddr, euid_ptr: Vaddr, suid_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getresuid(ruid_ptr: Vaddr, euid_ptr: Vaddr, suid_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("ruid_ptr = 0x{ruid_ptr:x}, euid_ptr = 0x{euid_ptr:x}, suid_ptr = 0x{suid_ptr:x}");
|
debug!("ruid_ptr = 0x{ruid_ptr:x}, euid_ptr = 0x{euid_ptr:x}, suid_ptr = 0x{suid_ptr:x}");
|
||||||
|
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
|
|
||||||
let ruid = credentials.ruid();
|
let ruid = credentials.ruid();
|
||||||
write_val_to_user(ruid_ptr, &ruid)?;
|
user_space.write_val(ruid_ptr, &ruid)?;
|
||||||
|
|
||||||
let euid = credentials.euid();
|
let euid = credentials.euid();
|
||||||
write_val_to_user(euid_ptr, &euid)?;
|
user_space.write_val(euid_ptr, &euid)?;
|
||||||
|
|
||||||
let suid = credentials.suid();
|
let suid = credentials.suid();
|
||||||
write_val_to_user(suid_ptr, &suid)?;
|
user_space.write_val(suid_ptr, &suid)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,7 @@
|
|||||||
use int_to_c_enum::TryFromInt;
|
use int_to_c_enum::TryFromInt;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{prelude::*, process::posix_thread::PosixThreadExt, time::timeval_t};
|
||||||
prelude::*, process::posix_thread::PosixThreadExt, time::timeval_t, util::write_val_to_user,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)]
|
#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
@ -53,7 +51,7 @@ pub fn sys_getrusage(target: i32, rusage_addr: Vaddr) -> Result<SyscallReturn> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(rusage_addr, &rusage)?;
|
CurrentUserSpace::get().write_val(rusage_addr, &rusage)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
@ -4,10 +4,7 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::FileDesc,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{
|
util::net::{get_socket_from_fd, new_raw_socket_option, CSocketOptionLevel},
|
||||||
net::{get_socket_from_fd, new_raw_socket_option, CSocketOptionLevel},
|
|
||||||
read_val_from_user, write_val_to_user,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getsockopt(
|
pub fn sys_getsockopt(
|
||||||
@ -21,7 +18,9 @@ pub fn sys_getsockopt(
|
|||||||
if optval == 0 || optlen_addr == 0 {
|
if optval == 0 || optlen_addr == 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "optval or optlen_addr is null pointer");
|
return_errno_with_message!(Errno::EINVAL, "optval or optlen_addr is null pointer");
|
||||||
}
|
}
|
||||||
let optlen: u32 = read_val_from_user(optlen_addr)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
|
||||||
|
let optlen: u32 = user_space.read_val(optlen_addr)?;
|
||||||
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
|
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
|
||||||
|
|
||||||
let socket = get_socket_from_fd(sockfd)?;
|
let socket = get_socket_from_fd(sockfd)?;
|
||||||
@ -32,13 +31,9 @@ pub fn sys_getsockopt(
|
|||||||
|
|
||||||
socket.get_option(raw_option.as_sock_option_mut())?;
|
socket.get_option(raw_option.as_sock_option_mut())?;
|
||||||
|
|
||||||
let write_len = {
|
let write_len = raw_option.write_to_user(optval, optlen)?;
|
||||||
let current = current!();
|
|
||||||
let vmar = current.root_vmar();
|
|
||||||
raw_option.write_to_user(vmar, optval, optlen)?
|
|
||||||
};
|
|
||||||
|
|
||||||
write_val_to_user(optlen_addr, &(write_len as u32))?;
|
user_space.write_val(optlen_addr, &(write_len as u32))?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::{timeval_t, SystemTime},
|
time::{timeval_t, SystemTime},
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The use of the timezone structure is obsolete.
|
// The use of the timezone structure is obsolete.
|
||||||
@ -19,7 +18,7 @@ pub fn sys_gettimeofday(timeval_addr: Vaddr, /* timezone_addr: Vaddr */) -> Resu
|
|||||||
let time_duration = now.duration_since(&SystemTime::UNIX_EPOCH)?;
|
let time_duration = now.duration_since(&SystemTime::UNIX_EPOCH)?;
|
||||||
timeval_t::from(time_duration)
|
timeval_t::from(time_duration)
|
||||||
};
|
};
|
||||||
write_val_to_user(timeval_addr, &time_val)?;
|
CurrentUserSpace::get().write_val(timeval_addr, &time_val)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use crate::{
|
|||||||
utils::{IoctlCmd, StatusFlags},
|
utils::{IoctlCmd, StatusFlags},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -21,14 +20,14 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
|
|||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
let res = match ioctl_cmd {
|
let res = match ioctl_cmd {
|
||||||
IoctlCmd::FIONBIO => {
|
IoctlCmd::FIONBIO => {
|
||||||
let is_nonblocking = read_val_from_user::<i32>(arg)? != 0;
|
let is_nonblocking = CurrentUserSpace::get().read_val::<i32>(arg)? != 0;
|
||||||
let mut flags = file.status_flags();
|
let mut flags = file.status_flags();
|
||||||
flags.set(StatusFlags::O_NONBLOCK, is_nonblocking);
|
flags.set(StatusFlags::O_NONBLOCK, is_nonblocking);
|
||||||
file.set_status_flags(flags)?;
|
file.set_status_flags(flags)?;
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
IoctlCmd::FIOASYNC => {
|
IoctlCmd::FIOASYNC => {
|
||||||
let is_async = read_val_from_user::<i32>(arg)? != 0;
|
let is_async = CurrentUserSpace::get().read_val::<i32>(arg)? != 0;
|
||||||
let mut flags = file.status_flags();
|
let mut flags = file.status_flags();
|
||||||
|
|
||||||
// Set `O_ASYNC` flags will send `SIGIO` signal to a process when
|
// Set `O_ASYNC` flags will send `SIGIO` signal to a process when
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_linkat(
|
pub fn sys_linkat(
|
||||||
@ -18,8 +17,10 @@ pub fn sys_linkat(
|
|||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let old_path = read_cstring_from_user(old_path_addr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
let new_path = read_cstring_from_user(new_path_addr, MAX_FILENAME_LEN)?;
|
|
||||||
|
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
||||||
|
let new_path = user_space.read_cstring(new_path_addr, MAX_FILENAME_LEN)?;
|
||||||
let flags =
|
let flags =
|
||||||
LinkFlags::from_bits(flags).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
LinkFlags::from_bits(flags).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, util::read_bytes_from_user};
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_madvise(start: Vaddr, len: usize, behavior: i32) -> Result<SyscallReturn> {
|
pub fn sys_madvise(start: Vaddr, len: usize, behavior: i32) -> Result<SyscallReturn> {
|
||||||
let behavior = MadviseBehavior::try_from(behavior)?;
|
let behavior = MadviseBehavior::try_from(behavior)?;
|
||||||
@ -15,7 +15,8 @@ pub fn sys_madvise(start: Vaddr, len: usize, behavior: i32) -> Result<SyscallRet
|
|||||||
| MadviseBehavior::MADV_WILLNEED => {
|
| MadviseBehavior::MADV_WILLNEED => {
|
||||||
// perform a read at first
|
// perform a read at first
|
||||||
let mut buffer = vec![0u8; len];
|
let mut buffer = vec![0u8; len];
|
||||||
read_bytes_from_user(start, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
CurrentUserSpace::get()
|
||||||
|
.read_bytes(start, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
||||||
}
|
}
|
||||||
MadviseBehavior::MADV_DONTNEED => {
|
MadviseBehavior::MADV_DONTNEED => {
|
||||||
warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
|
warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
|
||||||
|
@ -9,11 +9,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path = {:?}, mode = {}", dirfd, path, mode);
|
debug!("dirfd = {}, path = {:?}, mode = {}", dirfd, path, mode);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -10,7 +10,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::{constants::MAX_FILENAME_LEN, stat::FileType},
|
syscall::{constants::MAX_FILENAME_LEN, stat::FileType},
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_mknodat(
|
pub fn sys_mknodat(
|
||||||
@ -19,7 +18,7 @@ pub fn sys_mknodat(
|
|||||||
mode: u16,
|
mode: u16,
|
||||||
dev: usize,
|
dev: usize,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let inode_mode = {
|
let inode_mode = {
|
||||||
let mask_mode = mode & !current.umask().read().get();
|
let mask_mode = mode & !current.umask().read().get();
|
||||||
|
@ -11,7 +11,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The `data` argument is interpreted by the different filesystems.
|
/// The `data` argument is interpreted by the different filesystems.
|
||||||
@ -25,8 +24,9 @@ pub fn sys_mount(
|
|||||||
flags: u64,
|
flags: u64,
|
||||||
data: Vaddr,
|
data: Vaddr,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let devname = read_cstring_from_user(devname_addr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
let dirname = read_cstring_from_user(dirname_addr, MAX_FILENAME_LEN)?;
|
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
|
||||||
|
let dirname = user_space.read_cstring(dirname_addr, MAX_FILENAME_LEN)?;
|
||||||
let mount_flags = MountFlags::from_bits_truncate(flags as u32);
|
let mount_flags = MountFlags::from_bits_truncate(flags as u32);
|
||||||
debug!(
|
debug!(
|
||||||
"devname = {:?}, dirname = {:?}, fstype = 0x{:x}, flags = {:?}, data = 0x{:x}",
|
"devname = {:?}, dirname = {:?}, fstype = 0x{:x}, flags = {:?}, data = 0x{:x}",
|
||||||
@ -133,7 +133,7 @@ fn do_new_mount(devname: CString, fs_type: Vaddr, target_dentry: Arc<Dentry>) ->
|
|||||||
return_errno_with_message!(Errno::ENOTDIR, "mountpoint must be directory");
|
return_errno_with_message!(Errno::ENOTDIR, "mountpoint must be directory");
|
||||||
};
|
};
|
||||||
|
|
||||||
let fs_type = read_cstring_from_user(fs_type, MAX_FILENAME_LEN)?;
|
let fs_type = CurrentUserSpace::get().read_cstring(fs_type, MAX_FILENAME_LEN)?;
|
||||||
if fs_type.is_empty() {
|
if fs_type.is_empty() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "fs_type is empty");
|
return_errno_with_message!(Errno::EINVAL, "fs_type is empty");
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::Pauser,
|
process::signal::Pauser,
|
||||||
time::{clockid_t, timespec_t, TIMER_ABSTIME},
|
time::{clockid_t, timespec_t, TIMER_ABSTIME},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_nanosleep(
|
pub fn sys_nanosleep(
|
||||||
@ -53,7 +52,7 @@ fn do_clock_nanosleep(
|
|||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let request_time = {
|
let request_time = {
|
||||||
let timespec = read_val_from_user::<timespec_t>(request_timespec_addr)?;
|
let timespec = CurrentUserSpace::get().read_val::<timespec_t>(request_timespec_addr)?;
|
||||||
Duration::try_from(timespec)?
|
Duration::try_from(timespec)?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,7 +89,7 @@ fn do_clock_nanosleep(
|
|||||||
if remain_timespec_addr != 0 && !is_abs_time {
|
if remain_timespec_addr != 0 && !is_abs_time {
|
||||||
let remaining_duration = (start_time + timeout) - end_time;
|
let remaining_duration = (start_time + timeout) - end_time;
|
||||||
let remaining_timespec = timespec_t::from(remaining_duration);
|
let remaining_timespec = timespec_t::from(remaining_duration);
|
||||||
write_val_to_user(remain_timespec_addr, &remaining_timespec)?;
|
CurrentUserSpace::get().write_val(remain_timespec_addr, &remaining_timespec)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return_errno_with_message!(Errno::EINTR, "sleep was interrupted");
|
return_errno_with_message!(Errno::EINTR, "sleep was interrupted");
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_openat(
|
pub fn sys_openat(
|
||||||
@ -18,7 +17,7 @@ pub fn sys_openat(
|
|||||||
flags: u32,
|
flags: u32,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
"dirfd = {}, path = {:?}, flags = {}, mode = {}",
|
"dirfd = {}, path = {:?}, flags = {}, mode = {}",
|
||||||
dirfd, path, flags, mode
|
dirfd, path, flags, mode
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
utils::{Channel, CreationFlags, StatusFlags},
|
utils::{Channel, CreationFlags, StatusFlags},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
||||||
@ -40,7 +39,7 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
|||||||
};
|
};
|
||||||
debug!("pipe_fds: {:?}", pipe_fds);
|
debug!("pipe_fds: {:?}", pipe_fds);
|
||||||
|
|
||||||
if let Err(err) = write_val_to_user(fds, &pipe_fds) {
|
if let Err(err) = CurrentUserSpace::get().write_val(fds, &pipe_fds) {
|
||||||
file_table.close_file(pipe_fds.reader_fd).unwrap();
|
file_table.close_file(pipe_fds.reader_fd).unwrap();
|
||||||
file_table.close_file(pipe_fds.writer_fd).unwrap();
|
file_table.close_file(pipe_fds.writer_fd).unwrap();
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
@ -3,20 +3,15 @@
|
|||||||
use core::{cell::Cell, time::Duration};
|
use core::{cell::Cell, time::Duration};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller};
|
||||||
events::IoEvents,
|
|
||||||
fs::file_table::FileDesc,
|
|
||||||
prelude::*,
|
|
||||||
process::signal::Poller,
|
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32) -> Result<SyscallReturn> {
|
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32) -> Result<SyscallReturn> {
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let poll_fds = {
|
let poll_fds = {
|
||||||
let mut read_addr = fds;
|
let mut read_addr = fds;
|
||||||
let mut poll_fds = Vec::with_capacity(nfds as _);
|
let mut poll_fds = Vec::with_capacity(nfds as _);
|
||||||
for _ in 0..nfds {
|
for _ in 0..nfds {
|
||||||
let c_poll_fd = read_val_from_user::<c_pollfd>(read_addr)?;
|
let c_poll_fd = user_space.read_val::<c_pollfd>(read_addr)?;
|
||||||
let poll_fd = PollFd::from(c_poll_fd);
|
let poll_fd = PollFd::from(c_poll_fd);
|
||||||
// Always clear the revents fields first
|
// Always clear the revents fields first
|
||||||
poll_fd.revents().set(IoEvents::empty());
|
poll_fd.revents().set(IoEvents::empty());
|
||||||
@ -42,7 +37,7 @@ pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32) -> Result<SyscallReturn> {
|
|||||||
let mut write_addr = fds;
|
let mut write_addr = fds;
|
||||||
for pollfd in poll_fds {
|
for pollfd in poll_fds {
|
||||||
let c_poll_fd = c_pollfd::from(pollfd);
|
let c_poll_fd = c_pollfd::from(pollfd);
|
||||||
write_val_to_user(write_addr, &c_poll_fd)?;
|
user_space.write_val(write_addr, &c_poll_fd)?;
|
||||||
// FIXME: do we need to respect align of c_pollfd here?
|
// FIXME: do we need to respect align of c_pollfd here?
|
||||||
write_addr += core::mem::size_of::<c_pollfd>();
|
write_addr += core::mem::size_of::<c_pollfd>();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ use crate::{
|
|||||||
posix_thread::{PosixThreadExt, MAX_THREAD_NAME_LEN},
|
posix_thread::{PosixThreadExt, MAX_THREAD_NAME_LEN},
|
||||||
signal::sig_num::SigNum,
|
signal::sig_num::SigNum,
|
||||||
},
|
},
|
||||||
util::{read_cstring_from_user, write_bytes_to_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Result<SyscallReturn> {
|
pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Result<SyscallReturn> {
|
||||||
@ -33,7 +32,7 @@ pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Res
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(write_to_addr, &write_val)?;
|
CurrentUserSpace::get().write_val(write_to_addr, &write_val)?;
|
||||||
}
|
}
|
||||||
PrctlCmd::PR_GET_DUMPABLE => {
|
PrctlCmd::PR_GET_DUMPABLE => {
|
||||||
// TODO: when coredump is supported, return the actual value
|
// TODO: when coredump is supported, return the actual value
|
||||||
@ -50,7 +49,7 @@ pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Res
|
|||||||
let thread_name = posix_thread.thread_name().lock();
|
let thread_name = posix_thread.thread_name().lock();
|
||||||
if let Some(thread_name) = &*thread_name {
|
if let Some(thread_name) = &*thread_name {
|
||||||
if let Some(thread_name) = thread_name.name()? {
|
if let Some(thread_name) = thread_name.name()? {
|
||||||
write_bytes_to_user(
|
CurrentUserSpace::get().write_bytes(
|
||||||
write_to_addr,
|
write_to_addr,
|
||||||
&mut VmReader::from(thread_name.to_bytes_with_nul()),
|
&mut VmReader::from(thread_name.to_bytes_with_nul()),
|
||||||
)?;
|
)?;
|
||||||
@ -60,7 +59,8 @@ pub fn sys_prctl(option: i32, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> Res
|
|||||||
PrctlCmd::PR_SET_NAME(read_addr) => {
|
PrctlCmd::PR_SET_NAME(read_addr) => {
|
||||||
let mut thread_name = posix_thread.thread_name().lock();
|
let mut thread_name = posix_thread.thread_name().lock();
|
||||||
if let Some(thread_name) = &mut *thread_name {
|
if let Some(thread_name) = &mut *thread_name {
|
||||||
let new_thread_name = read_cstring_from_user(read_addr, MAX_THREAD_NAME_LEN)?;
|
let new_thread_name =
|
||||||
|
CurrentUserSpace::get().read_cstring(read_addr, MAX_THREAD_NAME_LEN)?;
|
||||||
thread_name.set_name(&new_thread_name)?;
|
thread_name.set_name(&new_thread_name)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::write_bytes_to_user};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
pub fn sys_pread64(
|
pub fn sys_pread64(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -33,7 +33,8 @@ pub fn sys_pread64(
|
|||||||
let read_len = {
|
let read_len = {
|
||||||
let mut buffer = vec![0u8; user_buf_len];
|
let mut buffer = vec![0u8; user_buf_len];
|
||||||
let read_len = file.read_at(offset as usize, &mut buffer)?;
|
let read_len = file.read_at(offset as usize, &mut buffer)?;
|
||||||
write_bytes_to_user(user_buf_ptr, &mut VmReader::from(buffer.as_slice()))?;
|
CurrentUserSpace::get()
|
||||||
|
.write_bytes(user_buf_ptr, &mut VmReader::from(buffer.as_slice()))?;
|
||||||
read_len
|
read_len
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{Pid, ResourceType},
|
process::{Pid, ResourceType},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_prlimit64(
|
pub fn sys_prlimit64(
|
||||||
@ -22,10 +21,10 @@ pub fn sys_prlimit64(
|
|||||||
let mut resource_limits = current.resource_limits().lock();
|
let mut resource_limits = current.resource_limits().lock();
|
||||||
if old_rlim_addr != 0 {
|
if old_rlim_addr != 0 {
|
||||||
let rlimit = resource_limits.get_rlimit(resource);
|
let rlimit = resource_limits.get_rlimit(resource);
|
||||||
write_val_to_user(old_rlim_addr, rlimit)?;
|
CurrentUserSpace::get().write_val(old_rlim_addr, rlimit)?;
|
||||||
}
|
}
|
||||||
if new_rlim_addr != 0 {
|
if new_rlim_addr != 0 {
|
||||||
let new_rlimit = read_val_from_user(new_rlim_addr)?;
|
let new_rlimit = CurrentUserSpace::get().read_val(new_rlim_addr)?;
|
||||||
*resource_limits.get_rlimit_mut(resource) = new_rlimit;
|
*resource_limits.get_rlimit_mut(resource) = new_rlimit;
|
||||||
}
|
}
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
||||||
time::timespec_t,
|
time::timespec_t,
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_pselect6(
|
pub fn sys_pselect6(
|
||||||
@ -22,8 +21,9 @@ pub fn sys_pselect6(
|
|||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let old_simask = if sigmask_addr != 0 {
|
let old_simask = if sigmask_addr != 0 {
|
||||||
let sigmask_with_size: SigMaskWithSize = read_val_from_user(sigmask_addr)?;
|
let sigmask_with_size: SigMaskWithSize = user_space.read_val(sigmask_addr)?;
|
||||||
|
|
||||||
if !sigmask_with_size.is_valid() {
|
if !sigmask_with_size.is_valid() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "sigmask size is invalid")
|
return_errno_with_message!(Errno::EINVAL, "sigmask size is invalid")
|
||||||
@ -38,7 +38,7 @@ pub fn sys_pselect6(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let timeout = if timespec_addr != 0 {
|
let timeout = if timespec_addr != 0 {
|
||||||
let time_spec: timespec_t = read_val_from_user(timespec_addr)?;
|
let time_spec: timespec_t = user_space.read_val(timespec_addr)?;
|
||||||
Some(Duration::try_from(time_spec)?)
|
Some(Duration::try_from(time_spec)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::read_bytes_from_user};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
pub fn sys_pwrite64(
|
pub fn sys_pwrite64(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -30,7 +30,7 @@ pub fn sys_pwrite64(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut buffer = vec![0u8; user_buf_len];
|
let mut buffer = vec![0u8; user_buf_len];
|
||||||
read_bytes_from_user(user_buf_ptr, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
CurrentUserSpace::get().read_bytes(user_buf_ptr, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
||||||
let write_len = file.write_at(offset as _, &buffer)?;
|
let write_len = file.write_at(offset as _, &buffer)?;
|
||||||
Ok(SyscallReturn::Return(write_len as _))
|
Ok(SyscallReturn::Return(write_len as _))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::write_bytes_to_user};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
pub fn sys_read(fd: FileDesc, user_buf_addr: Vaddr, buf_len: usize) -> Result<SyscallReturn> {
|
pub fn sys_read(fd: FileDesc, user_buf_addr: Vaddr, buf_len: usize) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
@ -23,7 +23,7 @@ pub fn sys_read(fd: FileDesc, user_buf_addr: Vaddr, buf_len: usize) -> Result<Sy
|
|||||||
let read_len = if buf_len != 0 {
|
let read_len = if buf_len != 0 {
|
||||||
let mut read_buf = vec![0u8; buf_len];
|
let mut read_buf = vec![0u8; buf_len];
|
||||||
let read_len = file.read(&mut read_buf)?;
|
let read_len = file.read(&mut read_buf)?;
|
||||||
write_bytes_to_user(
|
CurrentUserSpace::get().write_bytes(
|
||||||
user_buf_addr,
|
user_buf_addr,
|
||||||
&mut VmReader::from(&read_buf[..min(read_len, buf_len)]),
|
&mut VmReader::from(&read_buf[..min(read_len, buf_len)]),
|
||||||
)?;
|
)?;
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::{read_cstring_from_user, write_bytes_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_readlinkat(
|
pub fn sys_readlinkat(
|
||||||
@ -17,7 +16,8 @@ pub fn sys_readlinkat(
|
|||||||
usr_buf_addr: Vaddr,
|
usr_buf_addr: Vaddr,
|
||||||
usr_buf_len: usize,
|
usr_buf_len: usize,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
"dirfd = {}, path = {:?}, usr_buf_addr = 0x{:x}, usr_buf_len = 0x{:x}",
|
"dirfd = {}, path = {:?}, usr_buf_addr = 0x{:x}, usr_buf_len = 0x{:x}",
|
||||||
dirfd, path, usr_buf_addr, usr_buf_len
|
dirfd, path, usr_buf_addr, usr_buf_len
|
||||||
@ -35,7 +35,7 @@ pub fn sys_readlinkat(
|
|||||||
let linkpath = dentry.inode().read_link()?;
|
let linkpath = dentry.inode().read_link()?;
|
||||||
let bytes = linkpath.as_bytes();
|
let bytes = linkpath.as_bytes();
|
||||||
let write_len = bytes.len().min(usr_buf_len);
|
let write_len = bytes.len().min(usr_buf_len);
|
||||||
write_bytes_to_user(usr_buf_addr, &mut VmReader::from(&bytes[..write_len]))?;
|
user_space.write_bytes(usr_buf_addr, &mut VmReader::from(&bytes[..write_len]))?;
|
||||||
Ok(SyscallReturn::Return(write_len as _))
|
Ok(SyscallReturn::Return(write_len as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,11 @@ use crate::{
|
|||||||
fs::file_table::FileDesc,
|
fs::file_table::FileDesc,
|
||||||
net::socket::SendRecvFlags,
|
net::socket::SendRecvFlags,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{
|
util::net::{get_socket_from_fd, CUserMsgHdr},
|
||||||
net::{get_socket_from_fd, CUserMsgHdr},
|
|
||||||
read_val_from_user,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_recvmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result<SyscallReturn> {
|
pub fn sys_recvmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result<SyscallReturn> {
|
||||||
let c_user_msghdr: CUserMsgHdr = read_val_from_user(user_msghdr_ptr)?;
|
let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(user_msghdr_ptr)?;
|
||||||
let flags = SendRecvFlags::from_bits_truncate(flags);
|
let flags = SendRecvFlags::from_bits_truncate(flags);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_renameat(
|
pub fn sys_renameat(
|
||||||
@ -18,8 +17,9 @@ pub fn sys_renameat(
|
|||||||
new_dirfd: FileDesc,
|
new_dirfd: FileDesc,
|
||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let old_path = read_cstring_from_user(old_path_addr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
let new_path = read_cstring_from_user(new_path_addr, MAX_FILENAME_LEN)?;
|
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
||||||
|
let new_path = user_space.read_cstring(new_path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
"old_dirfd = {}, old_path = {:?}, new_dirfd = {}, new_path = {:?}",
|
"old_dirfd = {}, old_path = {:?}, new_dirfd = {}, new_path = {:?}",
|
||||||
old_dirfd, old_path, new_dirfd, new_path
|
old_dirfd, old_path, new_dirfd, new_path
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rmdir(path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_rmdir(path_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -16,7 +15,7 @@ pub fn sys_rmdir(path_addr: Vaddr) -> Result<SyscallReturn> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn sys_rmdirat(dirfd: FileDesc, path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub(super) fn sys_rmdirat(dirfd: FileDesc, path_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
let path_addr = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path_addr = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path_addr = {:?}", dirfd, path_addr);
|
debug!("dirfd = {}, path_addr = {:?}", dirfd, path_addr);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -4,7 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::{c_types::sigaction_t, sig_action::SigAction, sig_num::SigNum},
|
process::signal::{c_types::sigaction_t, sig_action::SigAction, sig_num::SigNum},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigaction(
|
pub fn sys_rt_sigaction(
|
||||||
@ -26,10 +25,10 @@ pub fn sys_rt_sigaction(
|
|||||||
let old_action = sig_dispositions.get(sig_num);
|
let old_action = sig_dispositions.get(sig_num);
|
||||||
let old_action_c = old_action.as_c_type();
|
let old_action_c = old_action.as_c_type();
|
||||||
if old_sig_action_addr != 0 {
|
if old_sig_action_addr != 0 {
|
||||||
write_val_to_user(old_sig_action_addr, &old_action_c)?;
|
CurrentUserSpace::get().write_val(old_sig_action_addr, &old_action_c)?;
|
||||||
}
|
}
|
||||||
if sig_action_addr != 0 {
|
if sig_action_addr != 0 {
|
||||||
let sig_action_c = read_val_from_user::<sigaction_t>(sig_action_addr)?;
|
let sig_action_c = CurrentUserSpace::get().read_val::<sigaction_t>(sig_action_addr)?;
|
||||||
let sig_action = SigAction::try_from(sig_action_c).unwrap();
|
let sig_action = SigAction::try_from(sig_action_c).unwrap();
|
||||||
trace!("sig action = {:?}", sig_action);
|
trace!("sig action = {:?}", sig_action);
|
||||||
sig_dispositions.set(sig_num, sig_action);
|
sig_dispositions.set(sig_num, sig_action);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::posix_thread::PosixThreadExt, util::write_val_to_user};
|
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
||||||
|
|
||||||
pub fn sys_rt_sigpending(u_set_ptr: Vaddr, sigset_size: usize) -> Result<SyscallReturn> {
|
pub fn sys_rt_sigpending(u_set_ptr: Vaddr, sigset_size: usize) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
@ -27,6 +27,6 @@ fn do_rt_sigpending(set_ptr: Vaddr) -> Result<()> {
|
|||||||
sig_mask_value & sig_pending_value
|
sig_mask_value & sig_pending_value
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(set_ptr, &u64::from(combined_signals))?;
|
CurrentUserSpace::get().write_val(set_ptr, &u64::from(combined_signals))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
sig_mask::SigMask,
|
sig_mask::SigMask,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigprocmask(
|
pub fn sys_rt_sigprocmask(
|
||||||
@ -40,12 +39,12 @@ fn do_rt_sigprocmask(mask_op: MaskOp, set_ptr: Vaddr, oldset_ptr: Vaddr) -> Resu
|
|||||||
let old_sig_mask_value = posix_thread.sig_mask().load(Ordering::Relaxed);
|
let old_sig_mask_value = posix_thread.sig_mask().load(Ordering::Relaxed);
|
||||||
debug!("old sig mask value: 0x{:x}", old_sig_mask_value);
|
debug!("old sig mask value: 0x{:x}", old_sig_mask_value);
|
||||||
if oldset_ptr != 0 {
|
if oldset_ptr != 0 {
|
||||||
write_val_to_user(oldset_ptr, &old_sig_mask_value)?;
|
CurrentUserSpace::get().write_val(oldset_ptr, &old_sig_mask_value)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sig_mask_ref = posix_thread.sig_mask();
|
let sig_mask_ref = posix_thread.sig_mask();
|
||||||
if set_ptr != 0 {
|
if set_ptr != 0 {
|
||||||
let mut read_mask = read_val_from_user::<SigMask>(set_ptr)?;
|
let mut read_mask = CurrentUserSpace::get().read_val::<SigMask>(set_ptr)?;
|
||||||
match mask_op {
|
match mask_op {
|
||||||
MaskOp::Block => {
|
MaskOp::Block => {
|
||||||
// According to man pages, "it is not possible to block SIGKILL or SIGSTOP.
|
// According to man pages, "it is not possible to block SIGKILL or SIGSTOP.
|
||||||
|
@ -8,7 +8,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{posix_thread::PosixThreadExt, signal::c_types::ucontext_t},
|
process::{posix_thread::PosixThreadExt, signal::c_types::ucontext_t},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
||||||
@ -24,7 +23,7 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
|||||||
// However, for most glibc applications, the restorer codes is provided by glibc and RESTORER flag is set.
|
// However, for most glibc applications, the restorer codes is provided by glibc and RESTORER flag is set.
|
||||||
debug_assert!(sig_context_addr == context.stack_pointer() as Vaddr);
|
debug_assert!(sig_context_addr == context.stack_pointer() as Vaddr);
|
||||||
|
|
||||||
let ucontext = read_val_from_user::<ucontext_t>(sig_context_addr)?;
|
let ucontext = CurrentUserSpace::get().read_val::<ucontext_t>(sig_context_addr)?;
|
||||||
|
|
||||||
// If the sig stack is active and used by current handler, decrease handler counter.
|
// If the sig stack is active and used by current handler, decrease handler counter.
|
||||||
if let Some(sig_stack) = posix_thread.sig_stack().lock().as_mut() {
|
if let Some(sig_stack) = posix_thread.sig_stack().lock().as_mut() {
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
sig_mask::SigMask,
|
sig_mask::SigMask,
|
||||||
Pauser,
|
Pauser,
|
||||||
},
|
},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result<SyscallReturn> {
|
pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result<SyscallReturn> {
|
||||||
@ -23,7 +22,7 @@ pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result<Sys
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sigmask = {
|
let sigmask = {
|
||||||
let mut mask: SigMask = read_val_from_user(sigmask_addr)?;
|
let mut mask: SigMask = CurrentUserSpace::get().read_val(sigmask_addr)?;
|
||||||
// It is not possible to block SIGKILL or SIGSTOP,
|
// It is not possible to block SIGKILL or SIGSTOP,
|
||||||
// specifying these signals in mask has no effect.
|
// specifying these signals in mask has no effect.
|
||||||
mask -= SIGKILL;
|
mask -= SIGKILL;
|
||||||
|
@ -6,7 +6,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{process_table, Pid},
|
process::{process_table, Pid},
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn get_num_cpus() -> usize {
|
fn get_num_cpus() -> usize {
|
||||||
@ -41,7 +40,7 @@ pub fn sys_sched_getaffinity(
|
|||||||
|
|
||||||
let dummy_cpu_set = cpu_set_t::new(num_cpus);
|
let dummy_cpu_set = cpu_set_t::new(num_cpus);
|
||||||
|
|
||||||
write_val_to_user(cpu_set_ptr, &dummy_cpu_set)?;
|
CurrentUserSpace::get().write_val(cpu_set_ptr, &dummy_cpu_set)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,7 @@ use super::{
|
|||||||
poll::{do_poll, PollFd},
|
poll::{do_poll, PollFd},
|
||||||
SyscallReturn,
|
SyscallReturn,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, time::timeval_t};
|
||||||
events::IoEvents,
|
|
||||||
fs::file_table::FileDesc,
|
|
||||||
prelude::*,
|
|
||||||
time::timeval_t,
|
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn sys_select(
|
pub fn sys_select(
|
||||||
nfds: FileDesc,
|
nfds: FileDesc,
|
||||||
@ -26,7 +20,7 @@ pub fn sys_select(
|
|||||||
let timeout = if timeval_addr == 0 {
|
let timeout = if timeval_addr == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let timeval = read_val_from_user::<timeval_t>(timeval_addr)?;
|
let timeval = CurrentUserSpace::get().read_val::<timeval_t>(timeval_addr)?;
|
||||||
Some(Duration::from(timeval))
|
Some(Duration::from(timeval))
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,11 +38,12 @@ pub fn do_sys_select(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "nfds is negative or exceeds the FD_SETSIZE");
|
return_errno_with_message!(Errno::EINVAL, "nfds is negative or exceeds the FD_SETSIZE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let get_fdset = |fdset_addr: Vaddr| -> Result<Option<FdSet>> {
|
let get_fdset = |fdset_addr: Vaddr| -> Result<Option<FdSet>> {
|
||||||
let fdset = if fdset_addr == 0 {
|
let fdset = if fdset_addr == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let fdset = read_val_from_user::<FdSet>(fdset_addr)?;
|
let fdset = user_space.read_val::<FdSet>(fdset_addr)?;
|
||||||
Some(fdset)
|
Some(fdset)
|
||||||
};
|
};
|
||||||
Ok(fdset)
|
Ok(fdset)
|
||||||
@ -78,7 +73,7 @@ pub fn do_sys_select(
|
|||||||
let set_fdset = |fdset_addr: Vaddr, fdset: Option<FdSet>| -> Result<()> {
|
let set_fdset = |fdset_addr: Vaddr, fdset: Option<FdSet>| -> Result<()> {
|
||||||
if let Some(fdset) = fdset {
|
if let Some(fdset) = fdset {
|
||||||
debug_assert!(fdset_addr != 0);
|
debug_assert!(fdset_addr != 0);
|
||||||
write_val_to_user(fdset_addr, &fdset)?;
|
user_space.write_val(fdset_addr, &fdset)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
fs::file_table::FileDesc,
|
|
||||||
prelude::*,
|
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn sys_sendfile(
|
pub fn sys_sendfile(
|
||||||
out_fd: FileDesc,
|
out_fd: FileDesc,
|
||||||
@ -18,7 +14,7 @@ pub fn sys_sendfile(
|
|||||||
let offset = if offset_ptr == 0 {
|
let offset = if offset_ptr == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let offset: isize = read_val_from_user(offset_ptr)?;
|
let offset: isize = CurrentUserSpace::get().read_val(offset_ptr)?;
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
@ -113,7 +109,7 @@ pub fn sys_sendfile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(offset) = offset {
|
if let Some(offset) = offset {
|
||||||
write_val_to_user(offset_ptr, &(offset as isize))?;
|
CurrentUserSpace::get().write_val(offset_ptr, &(offset as isize))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(total_len as _))
|
Ok(SyscallReturn::Return(total_len as _))
|
||||||
|
@ -5,14 +5,11 @@ use crate::{
|
|||||||
fs::file_table::FileDesc,
|
fs::file_table::FileDesc,
|
||||||
net::socket::{MessageHeader, SendRecvFlags},
|
net::socket::{MessageHeader, SendRecvFlags},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{
|
util::net::{get_socket_from_fd, CUserMsgHdr},
|
||||||
net::{get_socket_from_fd, CUserMsgHdr},
|
|
||||||
read_val_from_user,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_sendmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result<SyscallReturn> {
|
pub fn sys_sendmsg(sockfd: FileDesc, user_msghdr_ptr: Vaddr, flags: i32) -> Result<SyscallReturn> {
|
||||||
let c_user_msghdr: CUserMsgHdr = read_val_from_user(user_msghdr_ptr)?;
|
let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(user_msghdr_ptr)?;
|
||||||
let flags = SendRecvFlags::from_bits_truncate(flags);
|
let flags = SendRecvFlags::from_bits_truncate(flags);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -4,7 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::posix_thread::{PosixThreadExt, RobustListHead},
|
process::posix_thread::{PosixThreadExt, RobustListHead},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_set_robust_list(robust_list_head_ptr: Vaddr, len: usize) -> Result<SyscallReturn> {
|
pub fn sys_set_robust_list(robust_list_head_ptr: Vaddr, len: usize) -> Result<SyscallReturn> {
|
||||||
@ -18,7 +17,8 @@ pub fn sys_set_robust_list(robust_list_head_ptr: Vaddr, len: usize) -> Result<Sy
|
|||||||
"The len is not equal to the size of robust list head"
|
"The len is not equal to the size of robust list head"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let robust_list_head: RobustListHead = read_val_from_user(robust_list_head_ptr)?;
|
let robust_list_head: RobustListHead =
|
||||||
|
CurrentUserSpace::get().read_val(robust_list_head_ptr)?;
|
||||||
debug!("{:x?}", robust_list_head);
|
debug!("{:x?}", robust_list_head);
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||||
|
@ -4,7 +4,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{credentials_mut, Gid},
|
process::{credentials_mut, Gid},
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_setgroups(size: usize, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_setgroups(size: usize, group_list_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -19,7 +18,7 @@ pub fn sys_setgroups(size: usize, group_list_addr: Vaddr) -> Result<SyscallRetur
|
|||||||
let mut new_groups = BTreeSet::new();
|
let mut new_groups = BTreeSet::new();
|
||||||
for idx in 0..size {
|
for idx in 0..size {
|
||||||
let addr = group_list_addr + idx * core::mem::size_of::<Gid>();
|
let addr = group_list_addr + idx * core::mem::size_of::<Gid>();
|
||||||
let gid = read_val_from_user(addr)?;
|
let gid = CurrentUserSpace::get().read_val(addr)?;
|
||||||
new_groups.insert(gid);
|
new_groups.insert(gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::{itimerval_t, timer::Timeout, timeval_t},
|
time::{itimerval_t, timer::Timeout, timeval_t},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `ItimerType` is used to differ the target timer for some timer-related syscalls.
|
/// `ItimerType` is used to differ the target timer for some timer-related syscalls.
|
||||||
@ -33,7 +32,8 @@ pub fn sys_setitimer(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
||||||
}
|
}
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let new_itimerval = read_val_from_user::<itimerval_t>(new_itimerval_addr)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let new_itimerval = user_space.read_val::<itimerval_t>(new_itimerval_addr)?;
|
||||||
let interval = Duration::from(new_itimerval.it_interval);
|
let interval = Duration::from(new_itimerval.it_interval);
|
||||||
let expire_time = Duration::from(new_itimerval.it_value);
|
let expire_time = Duration::from(new_itimerval.it_value);
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ pub fn sys_setitimer(
|
|||||||
it_interval: old_interval,
|
it_interval: old_interval,
|
||||||
it_value: remain,
|
it_value: remain,
|
||||||
};
|
};
|
||||||
write_val_to_user(old_itimerval_addr, &old_itimerval)?;
|
user_space.write_val(old_itimerval_addr, &old_itimerval)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.set_interval(interval);
|
timer.set_interval(interval);
|
||||||
@ -89,7 +89,7 @@ pub fn sys_getitimer(itimer_type: i32, itimerval_addr: Vaddr) -> Result<SyscallR
|
|||||||
it_interval: interval,
|
it_interval: interval,
|
||||||
it_value: remain,
|
it_value: remain,
|
||||||
};
|
};
|
||||||
write_val_to_user(itimerval_addr, &itimerval)?;
|
CurrentUserSpace::get().write_val(itimerval_addr, &itimerval)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,7 @@ pub fn sys_setsockopt(
|
|||||||
let raw_option = {
|
let raw_option = {
|
||||||
let mut option = new_raw_socket_option(level, optname)?;
|
let mut option = new_raw_socket_option(level, optname)?;
|
||||||
|
|
||||||
let current = current!();
|
option.read_from_user(optval, optlen)?;
|
||||||
let vmar = current.root_vmar();
|
|
||||||
option.read_from_user(vmar, optval, optlen)?;
|
|
||||||
|
|
||||||
option
|
option
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
posix_thread::PosixThreadExt,
|
posix_thread::PosixThreadExt,
|
||||||
signal::{SigStack, SigStackFlags},
|
signal::{SigStack, SigStackFlags},
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_sigaltstack(sig_stack_addr: Vaddr, old_sig_stack_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_sigaltstack(sig_stack_addr: Vaddr, old_sig_stack_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -43,7 +42,7 @@ fn get_old_stack(old_sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Res
|
|||||||
debug!("old stack = {:?}", old_stack);
|
debug!("old stack = {:?}", old_stack);
|
||||||
|
|
||||||
let stack = stack_t::from(old_stack.clone());
|
let stack = stack_t::from(old_stack.clone());
|
||||||
write_val_to_user(old_sig_stack_addr, &stack)
|
CurrentUserSpace::get().write_val(old_sig_stack_addr, &stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Result<()> {
|
fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Result<()> {
|
||||||
@ -58,7 +57,7 @@ fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Result<
|
|||||||
}
|
}
|
||||||
|
|
||||||
let new_stack = {
|
let new_stack = {
|
||||||
let stack = read_val_from_user::<stack_t>(sig_stack_addr)?;
|
let stack = CurrentUserSpace::get().read_val::<stack_t>(sig_stack_addr)?;
|
||||||
SigStack::try_from(stack)?
|
SigStack::try_from(stack)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,10 +5,7 @@ use crate::{
|
|||||||
fs::file_table::{FdFlags, FileDesc},
|
fs::file_table::{FdFlags, FileDesc},
|
||||||
net::socket::unix::UnixStreamSocket,
|
net::socket::unix::UnixStreamSocket,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{
|
util::net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK},
|
||||||
net::{CSocketAddrFamily, Protocol, SockFlags, SockType, SOCK_TYPE_MASK},
|
|
||||||
write_val_to_user,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_socketpair(domain: i32, type_: i32, protocol: i32, sv: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_socketpair(domain: i32, type_: i32, protocol: i32, sv: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -46,7 +43,7 @@ pub fn sys_socketpair(domain: i32, type_: i32, protocol: i32, sv: Vaddr) -> Resu
|
|||||||
SocketFds(fd_a, fd_b)
|
SocketFds(fd_a, fd_b)
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(sv, &socket_fds)?;
|
CurrentUserSpace::get().write_val(sv, &socket_fds)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
time::timespec_t,
|
time::timespec_t,
|
||||||
util::{read_cstring_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
@ -22,7 +21,7 @@ pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
|||||||
let file_table = current.file_table().lock();
|
let file_table = current.file_table().lock();
|
||||||
let file = file_table.get_file(fd)?;
|
let file = file_table.get_file(fd)?;
|
||||||
let stat = Stat::from(file.metadata());
|
let stat = Stat::from(file.metadata());
|
||||||
write_val_to_user(stat_buf_ptr, &stat)?;
|
CurrentUserSpace::get().write_val(stat_buf_ptr, &stat)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +44,8 @@ pub fn sys_fstatat(
|
|||||||
stat_buf_ptr: Vaddr,
|
stat_buf_ptr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let filename = read_cstring_from_user(filename_ptr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let filename = user_space.read_cstring(filename_ptr, MAX_FILENAME_LEN)?;
|
||||||
let flags =
|
let flags =
|
||||||
StatFlags::from_bits(flags).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
StatFlags::from_bits(flags).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
||||||
debug!(
|
debug!(
|
||||||
@ -73,7 +73,7 @@ pub fn sys_fstatat(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let stat = Stat::from(dentry.metadata());
|
let stat = Stat::from(dentry.metadata());
|
||||||
write_val_to_user(stat_buf_ptr, &stat)?;
|
user_space.write_val(stat_buf_ptr, &stat)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@ use crate::{
|
|||||||
utils::{SuperBlock, PATH_MAX},
|
utils::{SuperBlock, PATH_MAX},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{read_cstring_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let path = user_space.read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,);
|
debug!("path = {:?}, statfs_buf_ptr = 0x{:x}", path, statfs_buf_ptr,);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
@ -23,7 +23,7 @@ pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr) -> Result<SyscallRetur
|
|||||||
current.fs().read().lookup(&fs_path)?
|
current.fs().read().lookup(&fs_path)?
|
||||||
};
|
};
|
||||||
let statfs = Statfs::from(dentry.fs().sb());
|
let statfs = Statfs::from(dentry.fs().sb());
|
||||||
write_val_to_user(statfs_buf_ptr, &statfs)?;
|
user_space.write_val(statfs_buf_ptr, &statfs)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn>
|
|||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
||||||
let dentry = inode_handle.dentry();
|
let dentry = inode_handle.dentry();
|
||||||
let statfs = Statfs::from(dentry.fs().sb());
|
let statfs = Statfs::from(dentry.fs().sb());
|
||||||
write_val_to_user(statfs_buf_ptr, &statfs)?;
|
CurrentUserSpace::get().write_val(statfs_buf_ptr, &statfs)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_symlinkat(
|
pub fn sys_symlinkat(
|
||||||
@ -17,8 +16,9 @@ pub fn sys_symlinkat(
|
|||||||
dirfd: FileDesc,
|
dirfd: FileDesc,
|
||||||
linkpath_addr: Vaddr,
|
linkpath_addr: Vaddr,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let target = read_cstring_from_user(target_addr, MAX_FILENAME_LEN)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
let linkpath = read_cstring_from_user(linkpath_addr, MAX_FILENAME_LEN)?;
|
let target = user_space.read_cstring(target_addr, MAX_FILENAME_LEN)?;
|
||||||
|
let linkpath = user_space.read_cstring(linkpath_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
"target = {:?}, dirfd = {}, linkpath = {:?}",
|
"target = {:?}, dirfd = {}, linkpath = {:?}",
|
||||||
target, dirfd, linkpath
|
target, dirfd, linkpath
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, time::SystemTime, util::write_val_to_user};
|
use crate::{prelude::*, time::SystemTime};
|
||||||
|
|
||||||
pub fn sys_time(tloc: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_time(tloc: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("tloc = 0x{tloc:x}");
|
debug!("tloc = 0x{tloc:x}");
|
||||||
@ -12,7 +12,7 @@ pub fn sys_time(tloc: Vaddr) -> Result<SyscallReturn> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if tloc != 0 {
|
if tloc != 0 {
|
||||||
write_val_to_user(tloc, &now_as_secs)?;
|
CurrentUserSpace::get().write_val(tloc, &now_as_secs)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(now_as_secs as _))
|
Ok(SyscallReturn::Return(now_as_secs as _))
|
||||||
|
@ -25,7 +25,6 @@ use crate::{
|
|||||||
clockid_t,
|
clockid_t,
|
||||||
clocks::{BootTimeClock, MonotonicClock, RealTimeClock},
|
clocks::{BootTimeClock, MonotonicClock, RealTimeClock},
|
||||||
},
|
},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_timer_create(
|
pub fn sys_timer_create(
|
||||||
@ -51,7 +50,7 @@ pub fn sys_timer_create(
|
|||||||
})
|
})
|
||||||
// Determine the timeout action through `sigevent`.
|
// Determine the timeout action through `sigevent`.
|
||||||
} else {
|
} else {
|
||||||
let sig_event = read_val_from_user::<sigevent_t>(sigevent_addr)?;
|
let sig_event = CurrentUserSpace::get().read_val::<sigevent_t>(sigevent_addr)?;
|
||||||
let sigev_notify = SigNotify::try_from(sig_event.sigev_notify)?;
|
let sigev_notify = SigNotify::try_from(sig_event.sigev_notify)?;
|
||||||
let signo = sig_event.sigev_signo;
|
let signo = sig_event.sigev_signo;
|
||||||
match sigev_notify {
|
match sigev_notify {
|
||||||
@ -152,7 +151,7 @@ pub fn sys_timer_create(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let timer_id = process_timer_manager.add_posix_timer(timer);
|
let timer_id = process_timer_manager.add_posix_timer(timer);
|
||||||
write_val_to_user(timer_id_addr, &timer_id)?;
|
CurrentUserSpace::get().write_val(timer_id_addr, &timer_id)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::{itimerspec_t, timer::Timeout, timespec_t, TIMER_ABSTIME},
|
time::{itimerspec_t, timer::Timeout, timespec_t, TIMER_ABSTIME},
|
||||||
util::{read_val_from_user, write_val_to_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_timer_settime(
|
pub fn sys_timer_settime(
|
||||||
@ -19,7 +18,8 @@ pub fn sys_timer_settime(
|
|||||||
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
return_errno_with_message!(Errno::EINVAL, "invalid pointer to new value");
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_itimerspec = read_val_from_user::<itimerspec_t>(new_itimerspec_addr)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let new_itimerspec = user_space.read_val::<itimerspec_t>(new_itimerspec_addr)?;
|
||||||
let interval = Duration::try_from(new_itimerspec.it_interval)?;
|
let interval = Duration::try_from(new_itimerspec.it_interval)?;
|
||||||
let expire_time = Duration::try_from(new_itimerspec.it_value)?;
|
let expire_time = Duration::try_from(new_itimerspec.it_value)?;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ pub fn sys_timer_settime(
|
|||||||
it_interval: old_interval,
|
it_interval: old_interval,
|
||||||
it_value: remain,
|
it_value: remain,
|
||||||
};
|
};
|
||||||
write_val_to_user(old_itimerspec_addr, &old_itimerspec)?;
|
user_space.write_val(old_itimerspec_addr, &old_itimerspec)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.set_interval(interval);
|
timer.set_interval(interval);
|
||||||
@ -71,7 +71,7 @@ pub fn sys_timer_gettime(timer_id: usize, itimerspec_addr: Vaddr) -> Result<Sysc
|
|||||||
it_interval: interval,
|
it_interval: interval,
|
||||||
it_value: remain,
|
it_value: remain,
|
||||||
};
|
};
|
||||||
write_val_to_user(itimerspec_addr, &itimerspec)?;
|
CurrentUserSpace::get().write_val(itimerspec_addr, &itimerspec)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_ftruncate(fd: FileDesc, len: isize) -> Result<SyscallReturn> {
|
pub fn sys_ftruncate(fd: FileDesc, len: isize) -> Result<SyscallReturn> {
|
||||||
@ -25,7 +24,7 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize) -> Result<SyscallReturn> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_truncate(path_ptr: Vaddr, len: isize) -> Result<SyscallReturn> {
|
pub fn sys_truncate(path_ptr: Vaddr, len: isize) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, PATH_MAX)?;
|
||||||
debug!("path = {:?}, length = {}", path, len);
|
debug!("path = {:?}, length = {}", path, len);
|
||||||
|
|
||||||
check_length(len)?;
|
check_length(len)?;
|
||||||
|
@ -5,11 +5,10 @@ use crate::{
|
|||||||
fs::fs_resolver::{FsPath, AT_FDCWD},
|
fs::fs_resolver::{FsPath, AT_FDCWD},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_umount(path_addr: Vaddr, flags: u64) -> Result<SyscallReturn> {
|
pub fn sys_umount(path_addr: Vaddr, flags: u64) -> Result<SyscallReturn> {
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
let umount_flags = UmountFlags::from_bits_truncate(flags as u32);
|
let umount_flags = UmountFlags::from_bits_truncate(flags as u32);
|
||||||
debug!("path = {:?}, flags = {:?}", path, umount_flags);
|
debug!("path = {:?}, flags = {:?}", path, umount_flags);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, util::write_val_to_user};
|
use crate::prelude::*;
|
||||||
|
|
||||||
// We don't use the real name and version of our os here. Instead, we pick up fake values witch is the same as the ones of linux.
|
// We don't use the real name and version of our os here. Instead, we pick up fake values witch is the same as the ones of linux.
|
||||||
// The values are used to fool glibc since glibc will check the version and os name.
|
// The values are used to fool glibc since glibc will check the version and os name.
|
||||||
@ -59,6 +59,6 @@ fn copy_cstring_to_u8_slice(src: &CStr, dst: &mut [u8]) {
|
|||||||
|
|
||||||
pub fn sys_uname(old_uname_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_uname(old_uname_addr: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("old uname addr = 0x{:x}", old_uname_addr);
|
debug!("old uname addr = 0x{:x}", old_uname_addr);
|
||||||
write_val_to_user(old_uname_addr, &*UTS_NAME)?;
|
CurrentUserSpace::get().write_val(old_uname_addr, &*UTS_NAME)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
util::read_cstring_from_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_unlinkat(dirfd: FileDesc, path_addr: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_unlinkat(dirfd: FileDesc, path_addr: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
||||||
@ -18,7 +17,7 @@ pub fn sys_unlinkat(dirfd: FileDesc, path_addr: Vaddr, flags: u32) -> Result<Sys
|
|||||||
return super::rmdir::sys_rmdirat(dirfd, path_addr);
|
return super::rmdir::sys_rmdirat(dirfd, path_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!("dirfd = {}, path = {:?}", dirfd, path);
|
debug!("dirfd = {}, path = {:?}", dirfd, path);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -11,7 +11,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::{clocks::RealTimeCoarseClock, timespec_t, timeval_t},
|
time::{clocks::RealTimeCoarseClock, timespec_t, timeval_t},
|
||||||
util::{read_cstring_from_user, read_val_from_user},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The 'sys_utimensat' system call sets the access and modification times of a file.
|
/// The 'sys_utimensat' system call sets the access and modification times of a file.
|
||||||
@ -77,7 +76,7 @@ pub fn sys_utime(pathname_ptr: Vaddr, utimbuf_ptr: Vaddr) -> Result<SyscallRetur
|
|||||||
pathname_ptr, utimbuf_ptr
|
pathname_ptr, utimbuf_ptr
|
||||||
);
|
);
|
||||||
let times = if utimbuf_ptr != 0 {
|
let times = if utimbuf_ptr != 0 {
|
||||||
let utimbuf = read_val_from_user::<Utimbuf>(utimbuf_ptr)?;
|
let utimbuf = CurrentUserSpace::get().read_val::<Utimbuf>(utimbuf_ptr)?;
|
||||||
let atime = timespec_t {
|
let atime = timespec_t {
|
||||||
sec: utimbuf.actime,
|
sec: utimbuf.actime,
|
||||||
nsec: 0,
|
nsec: 0,
|
||||||
@ -158,7 +157,7 @@ fn do_utimes(
|
|||||||
let pathname = if pathname_ptr == 0 {
|
let pathname = if pathname_ptr == 0 {
|
||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
let cstring = read_cstring_from_user(pathname_ptr, MAX_FILENAME_LEN)?;
|
let cstring = CurrentUserSpace::get().read_cstring(pathname_ptr, MAX_FILENAME_LEN)?;
|
||||||
cstring.to_string_lossy().into_owned()
|
cstring.to_string_lossy().into_owned()
|
||||||
};
|
};
|
||||||
let current = current!();
|
let current = current!();
|
||||||
@ -197,9 +196,10 @@ fn do_futimesat(dirfd: FileDesc, pathname_ptr: Vaddr, timeval_ptr: Vaddr) -> Res
|
|||||||
|
|
||||||
fn read_time_from_user<T: Pod>(time_ptr: Vaddr) -> Result<(T, T)> {
|
fn read_time_from_user<T: Pod>(time_ptr: Vaddr) -> Result<(T, T)> {
|
||||||
let mut time_addr = time_ptr;
|
let mut time_addr = time_ptr;
|
||||||
let autime = read_val_from_user::<T>(time_addr)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let autime = user_space.read_val::<T>(time_addr)?;
|
||||||
time_addr += core::mem::size_of::<T>();
|
time_addr += core::mem::size_of::<T>();
|
||||||
let mutime = read_val_from_user::<T>(time_addr)?;
|
let mutime = user_space.read_val::<T>(time_addr)?;
|
||||||
Ok((autime, mutime))
|
Ok((autime, mutime))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ use super::{getrusage::rusage_t, SyscallReturn};
|
|||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{wait_child_exit, ProcessFilter, WaitOptions},
|
process::{wait_child_exit, ProcessFilter, WaitOptions},
|
||||||
util::write_val_to_user,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_wait4(
|
pub fn sys_wait4(
|
||||||
@ -29,7 +28,7 @@ pub fn sys_wait4(
|
|||||||
|
|
||||||
let (return_pid, exit_code) = (process.pid(), process.exit_code().unwrap());
|
let (return_pid, exit_code) = (process.pid(), process.exit_code().unwrap());
|
||||||
if exit_status_ptr != 0 {
|
if exit_status_ptr != 0 {
|
||||||
write_val_to_user(exit_status_ptr as _, &exit_code)?;
|
CurrentUserSpace::get().write_val(exit_status_ptr as _, &exit_code)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if rusage_addr != 0 {
|
if rusage_addr != 0 {
|
||||||
@ -39,7 +38,7 @@ pub fn sys_wait4(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
write_val_to_user(rusage_addr, &rusage)?;
|
CurrentUserSpace::get().write_val(rusage_addr, &rusage)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(return_pid as _))
|
Ok(SyscallReturn::Return(return_pid as _))
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::read_bytes_from_user};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
const STDOUT: u64 = 1;
|
const STDOUT: u64 = 1;
|
||||||
const STDERR: u64 = 2;
|
const STDERR: u64 = 2;
|
||||||
@ -25,7 +25,8 @@ pub fn sys_write(fd: FileDesc, user_buf_ptr: Vaddr, user_buf_len: usize) -> Resu
|
|||||||
// the file discriptor. If no errors detected, return 0 successfully.
|
// the file discriptor. If no errors detected, return 0 successfully.
|
||||||
let write_len = if user_buf_len != 0 {
|
let write_len = if user_buf_len != 0 {
|
||||||
let mut buffer = vec![0u8; user_buf_len];
|
let mut buffer = vec![0u8; user_buf_len];
|
||||||
read_bytes_from_user(user_buf_ptr, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
CurrentUserSpace::get()
|
||||||
|
.read_bytes(user_buf_ptr, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
||||||
debug!("write content = {:?}", buffer);
|
debug!("write content = {:?}", buffer);
|
||||||
file.write(&buffer)?
|
file.write(&buffer)?
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::read_val_from_user;
|
use crate::prelude::*;
|
||||||
use crate::{
|
|
||||||
prelude::*,
|
|
||||||
util::{read_bytes_from_user, write_bytes_to_user},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A kernel space IO vector.
|
/// A kernel space IO vector.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -75,7 +71,7 @@ impl IoVec {
|
|||||||
assert_eq!(dst.len(), self.len);
|
assert_eq!(dst.len(), self.len);
|
||||||
assert!(!self.is_empty());
|
assert!(!self.is_empty());
|
||||||
|
|
||||||
read_bytes_from_user(self.base, &mut VmWriter::from(dst))
|
CurrentUserSpace::get().read_bytes(self.base, &mut VmWriter::from(dst))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes bytes from the `src` buffer
|
/// Writes bytes from the `src` buffer
|
||||||
@ -92,7 +88,7 @@ impl IoVec {
|
|||||||
assert_eq!(src.len(), self.len);
|
assert_eq!(src.len(), self.len);
|
||||||
assert!(!self.is_empty());
|
assert!(!self.is_empty());
|
||||||
|
|
||||||
write_bytes_to_user(self.base, &mut VmReader::from(src))
|
CurrentUserSpace::get().write_bytes(self.base, &mut VmReader::from(src))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads bytes to the `dst` buffer
|
/// Reads bytes to the `dst` buffer
|
||||||
@ -101,7 +97,7 @@ impl IoVec {
|
|||||||
/// If successful, returns the length of actually read bytes.
|
/// If successful, returns the length of actually read bytes.
|
||||||
pub fn read_from_user(&self, dst: &mut [u8]) -> Result<usize> {
|
pub fn read_from_user(&self, dst: &mut [u8]) -> Result<usize> {
|
||||||
let len = self.len.min(dst.len());
|
let len = self.len.min(dst.len());
|
||||||
read_bytes_from_user(self.base, &mut VmWriter::from(&mut dst[..len]))?;
|
CurrentUserSpace::get().read_bytes(self.base, &mut VmWriter::from(&mut dst[..len]))?;
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +107,7 @@ impl IoVec {
|
|||||||
/// If successful, returns the length of actually written bytes.
|
/// If successful, returns the length of actually written bytes.
|
||||||
pub fn write_to_user(&self, src: &[u8]) -> Result<usize> {
|
pub fn write_to_user(&self, src: &[u8]) -> Result<usize> {
|
||||||
let len = self.len.min(src.len());
|
let len = self.len.min(src.len());
|
||||||
write_bytes_to_user(self.base, &mut VmReader::from(&src[..len]))?;
|
CurrentUserSpace::get().write_bytes(self.base, &mut VmReader::from(&src[..len]))?;
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,9 +116,10 @@ impl IoVec {
|
|||||||
pub fn copy_iovs_from_user(start_addr: Vaddr, count: usize) -> Result<Box<[IoVec]>> {
|
pub fn copy_iovs_from_user(start_addr: Vaddr, count: usize) -> Result<Box<[IoVec]>> {
|
||||||
let mut io_vecs = Vec::with_capacity(count);
|
let mut io_vecs = Vec::with_capacity(count);
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
for idx in 0..count {
|
for idx in 0..count {
|
||||||
let addr = start_addr + idx * core::mem::size_of::<UserIoVec>();
|
let addr = start_addr + idx * core::mem::size_of::<UserIoVec>();
|
||||||
let uiov = read_val_from_user::<UserIoVec>(addr)?;
|
let uiov = user_space.read_val::<UserIoVec>(addr)?;
|
||||||
let iov = IoVec::try_from(uiov)?;
|
let iov = IoVec::try_from(uiov)?;
|
||||||
io_vecs.push(iov);
|
io_vecs.push(iov);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
|
|
||||||
use super::{ip::CSocketAddrInet, unix, vsock::CSocketAddrVm};
|
use super::{ip::CSocketAddrInet, unix, vsock::CSocketAddrVm};
|
||||||
use crate::{
|
use crate::{net::socket::SocketAddr, prelude::*};
|
||||||
net::socket::SocketAddr,
|
|
||||||
prelude::*,
|
|
||||||
util::{read_bytes_from_user, read_val_from_user, write_bytes_to_user, write_val_to_user},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Address family.
|
/// Address family.
|
||||||
///
|
///
|
||||||
@ -148,7 +144,7 @@ pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<Socket
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut storage = Storage::new_zeroed();
|
let mut storage = Storage::new_zeroed();
|
||||||
read_bytes_from_user(
|
CurrentUserSpace::get().read_bytes(
|
||||||
addr,
|
addr,
|
||||||
&mut VmWriter::from(&mut storage.as_bytes_mut()[..addr_len]),
|
&mut VmWriter::from(&mut storage.as_bytes_mut()[..addr_len]),
|
||||||
)?;
|
)?;
|
||||||
@ -204,11 +200,12 @@ pub fn write_socket_addr_to_user(
|
|||||||
dest: Vaddr,
|
dest: Vaddr,
|
||||||
max_len_ptr: Vaddr,
|
max_len_ptr: Vaddr,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let max_len = read_val_from_user::<i32>(max_len_ptr)?;
|
let user_space = CurrentUserSpace::get();
|
||||||
|
let max_len = user_space.read_val::<i32>(max_len_ptr)?;
|
||||||
|
|
||||||
let actual_len = write_socket_addr_with_max_len(socket_addr, dest, max_len)?;
|
let actual_len = write_socket_addr_with_max_len(socket_addr, dest, max_len)?;
|
||||||
|
|
||||||
write_val_to_user(max_len_ptr, &actual_len)
|
user_space.write_val(max_len_ptr, &actual_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a socket address to the user space.
|
/// Writes a socket address to the user space.
|
||||||
@ -238,12 +235,13 @@ pub fn write_socket_addr_with_max_len(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let user_space = CurrentUserSpace::get();
|
||||||
let actual_len = match socket_addr {
|
let actual_len = match socket_addr {
|
||||||
SocketAddr::IPv4(addr, port) => {
|
SocketAddr::IPv4(addr, port) => {
|
||||||
let socket_addr = CSocketAddrInet::from((*addr, *port));
|
let socket_addr = CSocketAddrInet::from((*addr, *port));
|
||||||
let actual_len = size_of::<CSocketAddrInet>();
|
let actual_len = size_of::<CSocketAddrInet>();
|
||||||
let written_len = min(actual_len, max_len as _);
|
let written_len = min(actual_len, max_len as _);
|
||||||
write_bytes_to_user(
|
user_space.write_bytes(
|
||||||
dest,
|
dest,
|
||||||
&mut VmReader::from(&socket_addr.as_bytes()[..written_len]),
|
&mut VmReader::from(&socket_addr.as_bytes()[..written_len]),
|
||||||
)?;
|
)?;
|
||||||
@ -251,14 +249,14 @@ pub fn write_socket_addr_with_max_len(
|
|||||||
}
|
}
|
||||||
SocketAddr::Unix(addr) => unix::into_c_bytes_and(addr, |bytes| {
|
SocketAddr::Unix(addr) => unix::into_c_bytes_and(addr, |bytes| {
|
||||||
let written_len = min(bytes.len(), max_len as _);
|
let written_len = min(bytes.len(), max_len as _);
|
||||||
write_bytes_to_user(dest, &mut VmReader::from(&bytes[..written_len]))?;
|
user_space.write_bytes(dest, &mut VmReader::from(&bytes[..written_len]))?;
|
||||||
Ok::<usize, Error>(bytes.len())
|
Ok::<usize, Error>(bytes.len())
|
||||||
})?,
|
})?,
|
||||||
SocketAddr::Vsock(addr) => {
|
SocketAddr::Vsock(addr) => {
|
||||||
let socket_addr = CSocketAddrVm::from(*addr);
|
let socket_addr = CSocketAddrVm::from(*addr);
|
||||||
let actual_len = size_of::<CSocketAddrVm>();
|
let actual_len = size_of::<CSocketAddrVm>();
|
||||||
let written_len = min(actual_len, max_len as _);
|
let written_len = min(actual_len, max_len as _);
|
||||||
write_bytes_to_user(
|
user_space.write_bytes(
|
||||||
dest,
|
dest,
|
||||||
&mut VmReader::from(&socket_addr.as_bytes()[..written_len]),
|
&mut VmReader::from(&socket_addr.as_bytes()[..written_len]),
|
||||||
)?;
|
)?;
|
||||||
|
@ -51,9 +51,7 @@
|
|||||||
//! At the syscall level, the interface is unified for all options and does not need to be modified.
|
//! At the syscall level, the interface is unified for all options and does not need to be modified.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use aster_rights::Full;
|
use crate::{net::socket::options::SocketOption, prelude::*};
|
||||||
|
|
||||||
use crate::{net::socket::options::SocketOption, prelude::*, vm::vmar::Vmar};
|
|
||||||
|
|
||||||
mod socket;
|
mod socket;
|
||||||
mod tcp;
|
mod tcp;
|
||||||
@ -62,9 +60,9 @@ mod utils;
|
|||||||
use self::{socket::new_socket_option, tcp::new_tcp_option};
|
use self::{socket::new_socket_option, tcp::new_tcp_option};
|
||||||
|
|
||||||
pub trait RawSocketOption: SocketOption {
|
pub trait RawSocketOption: SocketOption {
|
||||||
fn read_from_user(&mut self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<()>;
|
fn read_from_user(&mut self, addr: Vaddr, max_len: u32) -> Result<()>;
|
||||||
|
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize>;
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize>;
|
||||||
|
|
||||||
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption;
|
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption;
|
||||||
|
|
||||||
@ -76,24 +74,19 @@ pub trait RawSocketOption: SocketOption {
|
|||||||
macro_rules! impl_raw_socket_option {
|
macro_rules! impl_raw_socket_option {
|
||||||
($option:ty) => {
|
($option:ty) => {
|
||||||
impl RawSocketOption for $option {
|
impl RawSocketOption for $option {
|
||||||
fn read_from_user(
|
fn read_from_user(&mut self, addr: Vaddr, max_len: u32) -> Result<()> {
|
||||||
&mut self,
|
|
||||||
vmar: &Vmar<Full>,
|
|
||||||
addr: Vaddr,
|
|
||||||
max_len: u32,
|
|
||||||
) -> Result<()> {
|
|
||||||
use $crate::util::net::options::utils::ReadFromUser;
|
use $crate::util::net::options::utils::ReadFromUser;
|
||||||
|
|
||||||
let input = ReadFromUser::read_from_user(vmar, addr, max_len)?;
|
let input = ReadFromUser::read_from_user(addr, max_len)?;
|
||||||
self.set(input);
|
self.set(input);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
use $crate::util::net::options::utils::WriteToUser;
|
use $crate::util::net::options::utils::WriteToUser;
|
||||||
|
|
||||||
let output = self.get().unwrap();
|
let output = self.get().unwrap();
|
||||||
output.write_to_user(vmar, addr, max_len)
|
output.write_to_user(addr, max_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption {
|
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption {
|
||||||
@ -112,20 +105,15 @@ macro_rules! impl_raw_socket_option {
|
|||||||
macro_rules! impl_raw_sock_option_get_only {
|
macro_rules! impl_raw_sock_option_get_only {
|
||||||
($option:ty) => {
|
($option:ty) => {
|
||||||
impl RawSocketOption for $option {
|
impl RawSocketOption for $option {
|
||||||
fn read_from_user(
|
fn read_from_user(&mut self, _addr: Vaddr, _max_len: u32) -> Result<()> {
|
||||||
&mut self,
|
|
||||||
_vmar: &Vmar<Full>,
|
|
||||||
_addr: Vaddr,
|
|
||||||
_max_len: u32,
|
|
||||||
) -> Result<()> {
|
|
||||||
return_errno_with_message!(Errno::ENOPROTOOPT, "the option is getter-only");
|
return_errno_with_message!(Errno::ENOPROTOOPT, "the option is getter-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
use $crate::util::net::options::utils::WriteToUser;
|
use $crate::util::net::options::utils::WriteToUser;
|
||||||
|
|
||||||
let output = self.get().unwrap();
|
let output = self.get().unwrap();
|
||||||
output.write_to_user(vmar, addr, max_len)
|
output.write_to_user(addr, max_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption {
|
fn as_sock_option_mut(&mut self) -> &mut dyn SocketOption {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use aster_rights::Full;
|
|
||||||
|
|
||||||
use super::RawSocketOption;
|
use super::RawSocketOption;
|
||||||
use crate::{
|
use crate::{
|
||||||
impl_raw_sock_option_get_only, impl_raw_socket_option,
|
impl_raw_sock_option_get_only, impl_raw_socket_option,
|
||||||
@ -9,7 +7,6 @@ use crate::{
|
|||||||
Error, KeepAlive, Linger, RecvBuf, ReuseAddr, ReusePort, SendBuf, SocketOption,
|
Error, KeepAlive, Linger, RecvBuf, ReuseAddr, ReusePort, SendBuf, SocketOption,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
vm::vmar::Vmar,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Socket level options.
|
/// Socket level options.
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use aster_rights::Full;
|
|
||||||
|
|
||||||
use super::RawSocketOption;
|
use super::RawSocketOption;
|
||||||
use crate::{
|
use crate::{
|
||||||
impl_raw_socket_option,
|
impl_raw_socket_option,
|
||||||
net::socket::ip::stream::options::{Congestion, MaxSegment, NoDelay, WindowClamp},
|
net::socket::ip::stream::options::{Congestion, MaxSegment, NoDelay, WindowClamp},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::net::options::SocketOption,
|
util::net::options::SocketOption,
|
||||||
vm::vmar::Vmar,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Sock options for tcp socket.
|
/// Sock options for tcp socket.
|
||||||
|
@ -2,13 +2,9 @@
|
|||||||
|
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use aster_rights::Full;
|
|
||||||
use ostd::mm::VmIo;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
net::socket::{ip::stream::CongestionControl, LingerOption},
|
net::socket::{ip::stream::CongestionControl, LingerOption},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
vm::vmar::Vmar,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create an object by reading its C counterpart from the user space.
|
/// Create an object by reading its C counterpart from the user space.
|
||||||
@ -21,7 +17,7 @@ use crate::{
|
|||||||
/// from the user space must be validated by the kernel.
|
/// from the user space must be validated by the kernel.
|
||||||
pub trait ReadFromUser: Sized {
|
pub trait ReadFromUser: Sized {
|
||||||
/// Read a struct from user space by reading its C counterpart.
|
/// Read a struct from user space by reading its C counterpart.
|
||||||
fn read_from_user(vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<Self>;
|
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write an object to user space by writing its C counterpart.
|
/// Write an object to user space by writing its C counterpart.
|
||||||
@ -32,7 +28,7 @@ pub trait ReadFromUser: Sized {
|
|||||||
/// and write value in user space should be of same type.
|
/// and write value in user space should be of same type.
|
||||||
pub trait WriteToUser {
|
pub trait WriteToUser {
|
||||||
// Write a struct to user space by writing its C counterpart.
|
// Write a struct to user space by writing its C counterpart.
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize>;
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This macro is used to implement `ReadFromUser` and `WriteToUser` for types that
|
/// This macro is used to implement `ReadFromUser` and `WriteToUser` for types that
|
||||||
@ -46,23 +42,23 @@ pub trait WriteToUser {
|
|||||||
macro_rules! impl_read_write_for_pod_type {
|
macro_rules! impl_read_write_for_pod_type {
|
||||||
($pod_ty: ty) => {
|
($pod_ty: ty) => {
|
||||||
impl ReadFromUser for $pod_ty {
|
impl ReadFromUser for $pod_ty {
|
||||||
fn read_from_user(vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<Self> {
|
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> {
|
||||||
if (max_len as usize) < core::mem::size_of::<$pod_ty>() {
|
if (max_len as usize) < core::mem::size_of::<$pod_ty>() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
||||||
}
|
}
|
||||||
Ok(vmar.read_val::<$pod_ty>(addr)?)
|
crate::util::CurrentUserSpace::get().read_val::<$pod_ty>(addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteToUser for $pod_ty {
|
impl WriteToUser for $pod_ty {
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
let write_len = core::mem::size_of::<$pod_ty>();
|
let write_len = core::mem::size_of::<$pod_ty>();
|
||||||
|
|
||||||
if (max_len as usize) < write_len {
|
if (max_len as usize) < write_len {
|
||||||
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
vmar.write_val(addr, self)?;
|
crate::util::CurrentUserSpace::get().write_val(addr, self)?;
|
||||||
Ok(write_len)
|
Ok(write_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,19 +68,19 @@ macro_rules! impl_read_write_for_pod_type {
|
|||||||
impl_read_write_for_pod_type!(u32);
|
impl_read_write_for_pod_type!(u32);
|
||||||
|
|
||||||
impl ReadFromUser for bool {
|
impl ReadFromUser for bool {
|
||||||
fn read_from_user(vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<Self> {
|
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> {
|
||||||
if (max_len as usize) < core::mem::size_of::<i32>() {
|
if (max_len as usize) < core::mem::size_of::<i32>() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
let val = vmar.read_val::<i32>(addr)?;
|
let val = CurrentUserSpace::get().read_val::<i32>(addr)?;
|
||||||
|
|
||||||
Ok(val != 0)
|
Ok(val != 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteToUser for bool {
|
impl WriteToUser for bool {
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
let write_len = core::mem::size_of::<i32>();
|
let write_len = core::mem::size_of::<i32>();
|
||||||
|
|
||||||
if (max_len as usize) < write_len {
|
if (max_len as usize) < write_len {
|
||||||
@ -92,13 +88,13 @@ impl WriteToUser for bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let val = if *self { 1i32 } else { 0i32 };
|
let val = if *self { 1i32 } else { 0i32 };
|
||||||
vmar.write_val(addr, &val)?;
|
CurrentUserSpace::get().write_val(addr, &val)?;
|
||||||
Ok(write_len)
|
Ok(write_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteToUser for Option<Error> {
|
impl WriteToUser for Option<Error> {
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
let write_len = core::mem::size_of::<i32>();
|
let write_len = core::mem::size_of::<i32>();
|
||||||
|
|
||||||
if (max_len as usize) < write_len {
|
if (max_len as usize) < write_len {
|
||||||
@ -110,25 +106,25 @@ impl WriteToUser for Option<Error> {
|
|||||||
Some(error) => error.error() as i32,
|
Some(error) => error.error() as i32,
|
||||||
};
|
};
|
||||||
|
|
||||||
vmar.write_val(addr, &val)?;
|
CurrentUserSpace::get().write_val(addr, &val)?;
|
||||||
Ok(write_len)
|
Ok(write_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadFromUser for LingerOption {
|
impl ReadFromUser for LingerOption {
|
||||||
fn read_from_user(vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<Self> {
|
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> {
|
||||||
if (max_len as usize) < core::mem::size_of::<CLinger>() {
|
if (max_len as usize) < core::mem::size_of::<CLinger>() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
let c_linger = vmar.read_val::<CLinger>(addr)?;
|
let c_linger = CurrentUserSpace::get().read_val::<CLinger>(addr)?;
|
||||||
|
|
||||||
Ok(LingerOption::from(c_linger))
|
Ok(LingerOption::from(c_linger))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteToUser for LingerOption {
|
impl WriteToUser for LingerOption {
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
let write_len = core::mem::size_of::<CLinger>();
|
let write_len = core::mem::size_of::<CLinger>();
|
||||||
|
|
||||||
if (max_len as usize) < write_len {
|
if (max_len as usize) < write_len {
|
||||||
@ -136,22 +132,22 @@ impl WriteToUser for LingerOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let linger = CLinger::from(*self);
|
let linger = CLinger::from(*self);
|
||||||
vmar.write_val(addr, &linger)?;
|
CurrentUserSpace::get().write_val(addr, &linger)?;
|
||||||
Ok(write_len)
|
Ok(write_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadFromUser for CongestionControl {
|
impl ReadFromUser for CongestionControl {
|
||||||
fn read_from_user(vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<Self> {
|
fn read_from_user(addr: Vaddr, max_len: u32) -> Result<Self> {
|
||||||
let mut bytes = vec![0; max_len as usize];
|
let mut bytes = vec![0; max_len as usize];
|
||||||
vmar.read_bytes(addr, &mut bytes)?;
|
CurrentUserSpace::get().read_bytes(addr, &mut VmWriter::from(bytes.as_mut_slice()))?;
|
||||||
let name = String::from_utf8(bytes).unwrap();
|
let name = String::from_utf8(bytes).unwrap();
|
||||||
CongestionControl::new(&name)
|
CongestionControl::new(&name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteToUser for CongestionControl {
|
impl WriteToUser for CongestionControl {
|
||||||
fn write_to_user(&self, vmar: &Vmar<Full>, addr: Vaddr, max_len: u32) -> Result<usize> {
|
fn write_to_user(&self, addr: Vaddr, max_len: u32) -> Result<usize> {
|
||||||
let name = self.name().as_bytes();
|
let name = self.name().as_bytes();
|
||||||
|
|
||||||
let write_len = name.len();
|
let write_len = name.len();
|
||||||
@ -159,7 +155,7 @@ impl WriteToUser for CongestionControl {
|
|||||||
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
return_errno_with_message!(Errno::EINVAL, "max_len is too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
vmar.write_bytes(addr, name)?;
|
CurrentUserSpace::get().write_bytes(addr, &mut VmReader::from(name))?;
|
||||||
|
|
||||||
Ok(write_len)
|
Ok(write_len)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user