mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13:23 +00:00
Allow passing the process Context
to syscall handlers
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
19ad2a2eb4
commit
66a37da214
238
kernel/aster-nix/src/context.rs
Normal file
238
kernel/aster-nix/src/context.rs
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//! The context that can be accessed from the current task, thread or process.
|
||||||
|
|
||||||
|
use core::mem;
|
||||||
|
|
||||||
|
use ostd::{
|
||||||
|
mm::{UserSpace, VmReader, VmSpace, VmWriter},
|
||||||
|
task::Task,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
prelude::*,
|
||||||
|
process::{posix_thread::PosixThread, Process},
|
||||||
|
thread::Thread,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The context that can be accessed from the current POSIX thread.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Context<'a> {
|
||||||
|
pub process: &'a Process,
|
||||||
|
pub posix_thread: &'a PosixThread,
|
||||||
|
pub thread: &'a Thread,
|
||||||
|
pub task: &'a Task,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context<'_> {
|
||||||
|
/// Gets the userspace of the current task.
|
||||||
|
pub fn get_user_space(&self) -> CurrentUserSpace {
|
||||||
|
CurrentUserSpace(self.task.user_space().unwrap().vm_space().clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The user's memory space of the current task.
|
||||||
|
///
|
||||||
|
/// It provides methods to read from or write to the user space efficiently.
|
||||||
|
pub struct CurrentUserSpace(Arc<VmSpace>);
|
||||||
|
|
||||||
|
impl !Sync for CurrentUserSpace {}
|
||||||
|
impl !Send for CurrentUserSpace {}
|
||||||
|
|
||||||
|
impl CurrentUserSpace {
|
||||||
|
/// Gets the `CurrentUserSpace` from the current task.
|
||||||
|
///
|
||||||
|
/// This is slower than [`Context::get_user_space`]. Don't use this getter
|
||||||
|
/// If you get the access to the [`Context`].
|
||||||
|
pub fn get() -> Self {
|
||||||
|
let vm_space = {
|
||||||
|
let current_task = Task::current().unwrap();
|
||||||
|
let user_space = current_task.user_space().unwrap();
|
||||||
|
user_space.vm_space().clone()
|
||||||
|
};
|
||||||
|
Self(vm_space)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a reader to read data from the user space of the current task.
|
||||||
|
///
|
||||||
|
/// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range.
|
||||||
|
pub fn reader(&self, vaddr: Vaddr, len: usize) -> Result<VmReader<'_, UserSpace>> {
|
||||||
|
Ok(self.0.reader(vaddr, len)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a writer to write data into the user space.
|
||||||
|
///
|
||||||
|
/// Returns `Err` if the `vaddr` and `len` do not represent a user space memory range.
|
||||||
|
pub fn writer(&self, vaddr: Vaddr, len: usize) -> Result<VmWriter<'_, UserSpace>> {
|
||||||
|
Ok(self.0.writer(vaddr, len)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads bytes into the destination `VmWriter` from the user space of the
|
||||||
|
/// current process.
|
||||||
|
///
|
||||||
|
/// If the reading is completely successful, returns `Ok`. Otherwise, it
|
||||||
|
/// returns `Err`.
|
||||||
|
///
|
||||||
|
/// If the destination `VmWriter` (`dest`) is empty, this function still
|
||||||
|
/// checks if the current task and user space are available. If they are,
|
||||||
|
/// it returns `Ok`.
|
||||||
|
pub fn read_bytes(&self, src: Vaddr, dest: &mut VmWriter<'_>) -> Result<()> {
|
||||||
|
let copy_len = dest.avail();
|
||||||
|
|
||||||
|
if copy_len > 0 {
|
||||||
|
check_vaddr(src)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user_reader = self.reader(src, copy_len)?;
|
||||||
|
user_reader.read_fallible(dest).map_err(|err| err.0)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads a value typed `Pod` from the user space of the current process.
|
||||||
|
pub fn read_val<T: Pod>(&self, src: Vaddr) -> Result<T> {
|
||||||
|
if core::mem::size_of::<T>() > 0 {
|
||||||
|
check_vaddr(src)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user_reader = self.reader(src, core::mem::size_of::<T>())?;
|
||||||
|
Ok(user_reader.read_val()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes bytes from the source `VmReader` to the user space of the current
|
||||||
|
/// process.
|
||||||
|
///
|
||||||
|
/// If the writing is completely successful, returns `Ok`. Otherwise, it
|
||||||
|
/// returns `Err`.
|
||||||
|
///
|
||||||
|
/// If the source `VmReader` (`src`) is empty, this function still checks if
|
||||||
|
/// the current task and user space are available. If they are, it returns
|
||||||
|
/// `Ok`.
|
||||||
|
pub fn write_bytes(&self, dest: Vaddr, src: &mut VmReader<'_>) -> Result<()> {
|
||||||
|
let copy_len = src.remain();
|
||||||
|
|
||||||
|
if copy_len > 0 {
|
||||||
|
check_vaddr(dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user_writer = self.writer(dest, copy_len)?;
|
||||||
|
user_writer.write_fallible(src).map_err(|err| err.0)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes `val` to the user space of the current process.
|
||||||
|
pub fn write_val<T: Pod>(&self, dest: Vaddr, val: &T) -> Result<()> {
|
||||||
|
if core::mem::size_of::<T>() > 0 {
|
||||||
|
check_vaddr(dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user_writer = self.writer(dest, core::mem::size_of::<T>())?;
|
||||||
|
Ok(user_writer.write_val(val)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads a C string from the user space of the current process.
|
||||||
|
/// The length of the string should not exceed `max_len`,
|
||||||
|
/// including the final `\0` byte.
|
||||||
|
pub fn read_cstring(&self, vaddr: Vaddr, max_len: usize) -> Result<CString> {
|
||||||
|
if max_len > 0 {
|
||||||
|
check_vaddr(vaddr)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user_reader = self.reader(vaddr, max_len)?;
|
||||||
|
user_reader.read_cstring()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait providing the ability to read a C string from the user space
|
||||||
|
/// of the current process specifically for [`VmReader<'_, UserSpace>`], which
|
||||||
|
/// should reading the bytes iteratively in the reader until encountering
|
||||||
|
/// the end of the reader or reading a `\0` (is also included into the final C String).
|
||||||
|
pub trait ReadCString {
|
||||||
|
fn read_cstring(&mut self) -> Result<CString>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ReadCString for VmReader<'a, UserSpace> {
|
||||||
|
/// This implementation is inspired by
|
||||||
|
/// the `do_strncpy_from_user` function in Linux kernel.
|
||||||
|
/// The original Linux implementation can be found at:
|
||||||
|
/// <https://elixir.bootlin.com/linux/v6.0.9/source/lib/strncpy_from_user.c#L28>
|
||||||
|
fn read_cstring(&mut self) -> Result<CString> {
|
||||||
|
let max_len = self.remain();
|
||||||
|
let mut buffer: Vec<u8> = Vec::with_capacity(max_len);
|
||||||
|
|
||||||
|
macro_rules! read_one_byte_at_a_time_while {
|
||||||
|
($cond:expr) => {
|
||||||
|
while $cond {
|
||||||
|
let byte = self.read_val::<u8>()?;
|
||||||
|
buffer.push(byte);
|
||||||
|
if byte == 0 {
|
||||||
|
return Ok(CString::from_vec_with_nul(buffer)
|
||||||
|
.expect("We provided 0 but no 0 is found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the first few bytes to make `cur_addr` aligned with `size_of::<usize>`
|
||||||
|
read_one_byte_at_a_time_while!(
|
||||||
|
(self.cursor() as usize) % mem::size_of::<usize>() != 0 && buffer.len() < max_len
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle the rest of the bytes in bulk
|
||||||
|
while (buffer.len() + mem::size_of::<usize>()) <= max_len {
|
||||||
|
let Ok(word) = self.read_val::<usize>() else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if has_zero(word) {
|
||||||
|
for byte in word.to_ne_bytes() {
|
||||||
|
buffer.push(byte);
|
||||||
|
if byte == 0 {
|
||||||
|
return Ok(CString::from_vec_with_nul(buffer)
|
||||||
|
.expect("We provided 0 but no 0 is found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable!("The branch should never be reached unless `has_zero` has bugs.")
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.extend_from_slice(&word.to_ne_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the last few bytes that are not enough for a word
|
||||||
|
read_one_byte_at_a_time_while!(buffer.len() < max_len);
|
||||||
|
|
||||||
|
// Maximum length exceeded before finding the null terminator
|
||||||
|
return_errno_with_message!(Errno::EFAULT, "Fails to read CString from user");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines whether the value contains a zero byte.
|
||||||
|
///
|
||||||
|
/// This magic algorithm is from the Linux `has_zero` function:
|
||||||
|
/// <https://elixir.bootlin.com/linux/v6.0.9/source/include/asm-generic/word-at-a-time.h#L93>
|
||||||
|
const fn has_zero(value: usize) -> bool {
|
||||||
|
const ONE_BITS: usize = usize::from_le_bytes([0x01; mem::size_of::<usize>()]);
|
||||||
|
const HIGH_BITS: usize = usize::from_le_bytes([0x80; mem::size_of::<usize>()]);
|
||||||
|
|
||||||
|
value.wrapping_sub(ONE_BITS) & !value & HIGH_BITS != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the user space pointer is below the lowest userspace address.
|
||||||
|
///
|
||||||
|
/// If a pointer is below the lowest userspace address, it is likely to be a
|
||||||
|
/// NULL pointer. Reading from or writing to a NULL pointer should trigger a
|
||||||
|
/// segmentation fault.
|
||||||
|
///
|
||||||
|
/// If it is not checked here, a kernel page fault will happen and we would
|
||||||
|
/// deny the access in the page fault handler either. It may save a page fault
|
||||||
|
/// in some occasions. More importantly, double page faults may not be handled
|
||||||
|
/// quite well on some platforms.
|
||||||
|
fn check_vaddr(va: Vaddr) -> Result<()> {
|
||||||
|
if va < crate::vm::vmar::ROOT_VMAR_LOWEST_ADDR {
|
||||||
|
Err(Error::with_message(
|
||||||
|
Errno::EFAULT,
|
||||||
|
"Bad user space pointer specified",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,7 @@ extern crate getset;
|
|||||||
|
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
pub mod console;
|
pub mod console;
|
||||||
|
pub mod context;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod device;
|
pub mod device;
|
||||||
pub mod driver;
|
pub mod driver;
|
||||||
|
@ -50,11 +50,11 @@ macro_rules! current_thread {
|
|||||||
pub(crate) use lazy_static::lazy_static;
|
pub(crate) use lazy_static::lazy_static;
|
||||||
|
|
||||||
pub(crate) use crate::{
|
pub(crate) use crate::{
|
||||||
|
context::{Context, CurrentUserSpace, ReadCString},
|
||||||
current, current_thread,
|
current, current_thread,
|
||||||
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};
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
|
||||||
|
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ostd::{
|
use ostd::{
|
||||||
@ -19,7 +17,6 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::LinuxAbi,
|
cpu::LinuxAbi,
|
||||||
current_thread,
|
|
||||||
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
thread::{allocate_tid, thread_table, Thread, Tid},
|
thread::{allocate_tid, thread_table, Thread, Tid},
|
||||||
@ -129,16 +126,20 @@ impl CloneFlags {
|
|||||||
///
|
///
|
||||||
/// FIXME: currently, the child process or thread will be scheduled to run at once,
|
/// FIXME: currently, the child process or thread will be scheduled to run at once,
|
||||||
/// but this may not be the expected bahavior.
|
/// but this may not be the expected bahavior.
|
||||||
pub fn clone_child(parent_context: &UserContext, clone_args: CloneArgs) -> Result<Tid> {
|
pub fn clone_child(
|
||||||
|
ctx: &Context,
|
||||||
|
parent_context: &UserContext,
|
||||||
|
clone_args: CloneArgs,
|
||||||
|
) -> Result<Tid> {
|
||||||
clone_args.clone_flags.check_unsupported_flags()?;
|
clone_args.clone_flags.check_unsupported_flags()?;
|
||||||
if clone_args.clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
if clone_args.clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
||||||
let child_thread = clone_child_thread(parent_context, clone_args)?;
|
let child_thread = clone_child_thread(ctx, parent_context, clone_args)?;
|
||||||
child_thread.run();
|
child_thread.run();
|
||||||
|
|
||||||
let child_tid = child_thread.tid();
|
let child_tid = child_thread.tid();
|
||||||
Ok(child_tid)
|
Ok(child_tid)
|
||||||
} else {
|
} else {
|
||||||
let child_process = clone_child_process(parent_context, clone_args)?;
|
let child_process = clone_child_process(ctx, parent_context, clone_args)?;
|
||||||
child_process.run();
|
child_process.run();
|
||||||
|
|
||||||
let child_pid = child_process.pid();
|
let child_pid = child_process.pid();
|
||||||
@ -146,13 +147,23 @@ pub fn clone_child(parent_context: &UserContext, clone_args: CloneArgs) -> Resul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Result<Arc<Thread>> {
|
fn clone_child_thread(
|
||||||
|
ctx: &Context,
|
||||||
|
parent_context: &UserContext,
|
||||||
|
clone_args: CloneArgs,
|
||||||
|
) -> Result<Arc<Thread>> {
|
||||||
|
let Context {
|
||||||
|
process,
|
||||||
|
posix_thread,
|
||||||
|
thread: _,
|
||||||
|
task: _,
|
||||||
|
} = ctx;
|
||||||
|
|
||||||
let clone_flags = clone_args.clone_flags;
|
let clone_flags = clone_args.clone_flags;
|
||||||
let current = current!();
|
|
||||||
debug_assert!(clone_flags.contains(CloneFlags::CLONE_VM));
|
debug_assert!(clone_flags.contains(CloneFlags::CLONE_VM));
|
||||||
debug_assert!(clone_flags.contains(CloneFlags::CLONE_FILES));
|
debug_assert!(clone_flags.contains(CloneFlags::CLONE_FILES));
|
||||||
debug_assert!(clone_flags.contains(CloneFlags::CLONE_SIGHAND));
|
debug_assert!(clone_flags.contains(CloneFlags::CLONE_SIGHAND));
|
||||||
let child_root_vmar = current.root_vmar();
|
let child_root_vmar = process.root_vmar();
|
||||||
|
|
||||||
let child_user_space = {
|
let child_user_space = {
|
||||||
let child_vm_space = child_root_vmar.vm_space().clone();
|
let child_vm_space = child_root_vmar.vm_space().clone();
|
||||||
@ -168,14 +179,7 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re
|
|||||||
clone_sysvsem(clone_flags)?;
|
clone_sysvsem(clone_flags)?;
|
||||||
|
|
||||||
// Inherit sigmask from current thread
|
// Inherit sigmask from current thread
|
||||||
let sig_mask = {
|
let sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into();
|
||||||
let current_thread = current_thread!();
|
|
||||||
let current_posix_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
current_posix_thread
|
|
||||||
.sig_mask()
|
|
||||||
.load(Ordering::Relaxed)
|
|
||||||
.into()
|
|
||||||
};
|
|
||||||
|
|
||||||
let child_tid = allocate_tid();
|
let child_tid = allocate_tid();
|
||||||
let child_thread = {
|
let child_thread = {
|
||||||
@ -185,12 +189,12 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re
|
|||||||
};
|
};
|
||||||
|
|
||||||
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space, credentials)
|
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space, credentials)
|
||||||
.process(Arc::downgrade(¤t))
|
.process(posix_thread.weak_process())
|
||||||
.sig_mask(sig_mask);
|
.sig_mask(sig_mask);
|
||||||
thread_builder.build()
|
thread_builder.build()
|
||||||
};
|
};
|
||||||
|
|
||||||
current.threads().lock().push(child_thread.clone());
|
process.threads().lock().push(child_thread.clone());
|
||||||
|
|
||||||
let child_posix_thread = child_thread.as_posix_thread().unwrap();
|
let child_posix_thread = child_thread.as_posix_thread().unwrap();
|
||||||
clone_parent_settid(child_tid, clone_args.parent_tidptr, clone_flags)?;
|
clone_parent_settid(child_tid, clone_args.parent_tidptr, clone_flags)?;
|
||||||
@ -200,16 +204,22 @@ fn clone_child_thread(parent_context: &UserContext, clone_args: CloneArgs) -> Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn clone_child_process(
|
fn clone_child_process(
|
||||||
|
ctx: &Context,
|
||||||
parent_context: &UserContext,
|
parent_context: &UserContext,
|
||||||
clone_args: CloneArgs,
|
clone_args: CloneArgs,
|
||||||
) -> Result<Arc<Process>> {
|
) -> Result<Arc<Process>> {
|
||||||
let current = current!();
|
let Context {
|
||||||
let parent = Arc::downgrade(¤t);
|
process,
|
||||||
|
posix_thread,
|
||||||
|
thread: _,
|
||||||
|
task: _,
|
||||||
|
} = ctx;
|
||||||
|
|
||||||
let clone_flags = clone_args.clone_flags;
|
let clone_flags = clone_args.clone_flags;
|
||||||
|
|
||||||
// clone vm
|
// clone vm
|
||||||
let child_process_vm = {
|
let child_process_vm = {
|
||||||
let parent_process_vm = current.vm();
|
let parent_process_vm = process.vm();
|
||||||
clone_vm(parent_process_vm, clone_flags)?
|
clone_vm(parent_process_vm, clone_flags)?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -230,37 +240,33 @@ fn clone_child_process(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// clone file table
|
// clone file table
|
||||||
let child_file_table = clone_files(current.file_table(), clone_flags);
|
let child_file_table = clone_files(process.file_table(), clone_flags);
|
||||||
|
|
||||||
// clone fs
|
// clone fs
|
||||||
let child_fs = clone_fs(current.fs(), clone_flags);
|
let child_fs = clone_fs(process.fs(), clone_flags);
|
||||||
|
|
||||||
// clone umask
|
// clone umask
|
||||||
let child_umask = {
|
let child_umask = {
|
||||||
let parent_umask = current.umask().read().get();
|
let parent_umask = process.umask().read().get();
|
||||||
Arc::new(RwLock::new(FileCreationMask::new(parent_umask)))
|
Arc::new(RwLock::new(FileCreationMask::new(parent_umask)))
|
||||||
};
|
};
|
||||||
|
|
||||||
// clone sig dispositions
|
// clone sig dispositions
|
||||||
let child_sig_dispositions = clone_sighand(current.sig_dispositions(), clone_flags);
|
let child_sig_dispositions = clone_sighand(process.sig_dispositions(), clone_flags);
|
||||||
|
|
||||||
// clone system V semaphore
|
// clone system V semaphore
|
||||||
clone_sysvsem(clone_flags)?;
|
clone_sysvsem(clone_flags)?;
|
||||||
|
|
||||||
// inherit parent's sig mask
|
// inherit parent's sig mask
|
||||||
let child_sig_mask = {
|
let child_sig_mask = posix_thread.sig_mask().load(Ordering::Relaxed).into();
|
||||||
let current_thread = current_thread!();
|
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
posix_thread.sig_mask().load(Ordering::Relaxed).into()
|
|
||||||
};
|
|
||||||
|
|
||||||
// inherit parent's nice value
|
// inherit parent's nice value
|
||||||
let child_nice = current.nice().load(Ordering::Relaxed);
|
let child_nice = process.nice().load(Ordering::Relaxed);
|
||||||
|
|
||||||
let child_tid = allocate_tid();
|
let child_tid = allocate_tid();
|
||||||
|
|
||||||
let child = {
|
let child = {
|
||||||
let child_elf_path = current.executable_path();
|
let child_elf_path = process.executable_path();
|
||||||
let child_thread_builder = {
|
let child_thread_builder = {
|
||||||
let child_thread_name = ThreadName::new_from_executable_path(&child_elf_path)?;
|
let child_thread_name = ThreadName::new_from_executable_path(&child_elf_path)?;
|
||||||
|
|
||||||
@ -275,7 +281,7 @@ fn clone_child_process(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut process_builder =
|
let mut process_builder =
|
||||||
ProcessBuilder::new(child_tid, &child_elf_path, Arc::downgrade(¤t));
|
ProcessBuilder::new(child_tid, &child_elf_path, posix_thread.weak_process());
|
||||||
|
|
||||||
process_builder
|
process_builder
|
||||||
.main_thread_builder(child_thread_builder)
|
.main_thread_builder(child_thread_builder)
|
||||||
@ -297,7 +303,7 @@ fn clone_child_process(
|
|||||||
clone_child_settid(child_posix_thread, clone_args.child_tidptr, clone_flags)?;
|
clone_child_settid(child_posix_thread, clone_args.child_tidptr, clone_flags)?;
|
||||||
|
|
||||||
// Sets parent process and group for child process.
|
// Sets parent process and group for child process.
|
||||||
set_parent_and_group(¤t, &child);
|
set_parent_and_group(process, &child);
|
||||||
|
|
||||||
Ok(child)
|
Ok(child)
|
||||||
}
|
}
|
||||||
@ -421,7 +427,7 @@ fn clone_sysvsem(clone_flags: CloneFlags) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_parent_and_group(parent: &Arc<Process>, child: &Arc<Process>) {
|
fn set_parent_and_group(parent: &Process, child: &Arc<Process>) {
|
||||||
let process_group = parent.process_group().unwrap();
|
let process_group = parent.process_group().unwrap();
|
||||||
|
|
||||||
let mut process_table_mut = process_table::process_table_mut();
|
let mut process_table_mut = process_table::process_table_mut();
|
||||||
|
@ -80,6 +80,10 @@ impl PosixThread {
|
|||||||
self.process.upgrade().unwrap()
|
self.process.upgrade().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn weak_process(&self) -> Weak<Process> {
|
||||||
|
Weak::clone(&self.process)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn thread_name(&self) -> &Mutex<Option<ThreadName>> {
|
pub fn thread_name(&self) -> &Mutex<Option<ThreadName>> {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,12 @@ pub struct ThreadName {
|
|||||||
count: usize,
|
count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ThreadName {
|
||||||
|
fn default() -> Self {
|
||||||
|
ThreadName::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ThreadName {
|
impl ThreadName {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ThreadName {
|
ThreadName {
|
||||||
|
@ -14,6 +14,7 @@ pub fn sys_accept(
|
|||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ pub fn sys_accept4(
|
|||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
trace!("raw flags = 0x{:x}", flags);
|
trace!("raw flags = 0x{:x}", flags);
|
||||||
let flags = Flags::from_bits_truncate(flags);
|
let flags = Flags::from_bits_truncate(flags);
|
||||||
|
@ -10,7 +10,12 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_faccessat(
|
||||||
|
dirfd: FileDesc,
|
||||||
|
path_ptr: Vaddr,
|
||||||
|
mode: u16,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}",
|
"faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}",
|
||||||
dirfd, path_ptr, mode
|
dirfd, path_ptr, mode
|
||||||
@ -19,7 +24,7 @@ pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result<Sysc
|
|||||||
do_faccessat(dirfd, path_ptr, mode, 0)
|
do_faccessat(dirfd, path_ptr, mode, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_access(path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_access(path_ptr: Vaddr, mode: u16, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode);
|
debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode);
|
||||||
|
|
||||||
do_faccessat(AT_FDCWD, path_ptr, mode, 0)
|
do_faccessat(AT_FDCWD, path_ptr, mode, 0)
|
||||||
|
@ -5,7 +5,7 @@ use core::time::Duration;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, time::timer::Timeout};
|
use crate::{prelude::*, time::timer::Timeout};
|
||||||
|
|
||||||
pub fn sys_alarm(seconds: u32) -> Result<SyscallReturn> {
|
pub fn sys_alarm(seconds: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("seconds = {}", seconds);
|
debug!("seconds = {}", seconds);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -145,7 +145,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_BRK = 12 => sys_brk(args[..1]);
|
SYS_BRK = 12 => sys_brk(args[..1]);
|
||||||
SYS_RT_SIGACTION = 13 => sys_rt_sigaction(args[..4]);
|
SYS_RT_SIGACTION = 13 => sys_rt_sigaction(args[..4]);
|
||||||
SYS_RT_SIGPROCMASK = 14 => sys_rt_sigprocmask(args[..4]);
|
SYS_RT_SIGPROCMASK = 14 => sys_rt_sigprocmask(args[..4]);
|
||||||
SYS_RT_SIGRETURN = 15 => sys_rt_sigreturn(args[..0], &mut context);
|
SYS_RT_SIGRETURN = 15 => sys_rt_sigreturn(args[..0], &mut user_ctx);
|
||||||
SYS_IOCTL = 16 => sys_ioctl(args[..3]);
|
SYS_IOCTL = 16 => sys_ioctl(args[..3]);
|
||||||
SYS_PREAD64 = 17 => sys_pread64(args[..4]);
|
SYS_PREAD64 = 17 => sys_pread64(args[..4]);
|
||||||
SYS_PWRITE64 = 18 => sys_pwrite64(args[..4]);
|
SYS_PWRITE64 = 18 => sys_pwrite64(args[..4]);
|
||||||
@ -180,9 +180,9 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_SOCKETPAIR = 53 => sys_socketpair(args[..4]);
|
SYS_SOCKETPAIR = 53 => sys_socketpair(args[..4]);
|
||||||
SYS_SETSOCKOPT = 54 => sys_setsockopt(args[..5]);
|
SYS_SETSOCKOPT = 54 => sys_setsockopt(args[..5]);
|
||||||
SYS_GETSOCKOPT = 55 => sys_getsockopt(args[..5]);
|
SYS_GETSOCKOPT = 55 => sys_getsockopt(args[..5]);
|
||||||
SYS_CLONE = 56 => sys_clone(args[..5], &context);
|
SYS_CLONE = 56 => sys_clone(args[..5], &user_ctx);
|
||||||
SYS_FORK = 57 => sys_fork(args[..0], &context);
|
SYS_FORK = 57 => sys_fork(args[..0], &user_ctx);
|
||||||
SYS_EXECVE = 59 => sys_execve(args[..3], &mut context);
|
SYS_EXECVE = 59 => sys_execve(args[..3], &mut user_ctx);
|
||||||
SYS_EXIT = 60 => sys_exit(args[..1]);
|
SYS_EXIT = 60 => sys_exit(args[..1]);
|
||||||
SYS_WAIT4 = 61 => sys_wait4(args[..4]);
|
SYS_WAIT4 = 61 => sys_wait4(args[..4]);
|
||||||
SYS_KILL = 62 => sys_kill(args[..2]);
|
SYS_KILL = 62 => sys_kill(args[..2]);
|
||||||
@ -245,7 +245,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_GET_PRIORITY = 140 => sys_get_priority(args[..2]);
|
SYS_GET_PRIORITY = 140 => sys_get_priority(args[..2]);
|
||||||
SYS_SET_PRIORITY = 141 => sys_set_priority(args[..3]);
|
SYS_SET_PRIORITY = 141 => sys_set_priority(args[..3]);
|
||||||
SYS_PRCTL = 157 => sys_prctl(args[..5]);
|
SYS_PRCTL = 157 => sys_prctl(args[..5]);
|
||||||
SYS_ARCH_PRCTL = 158 => sys_arch_prctl(args[..2], &mut context);
|
SYS_ARCH_PRCTL = 158 => sys_arch_prctl(args[..2], &mut user_ctx);
|
||||||
SYS_CHROOT = 161 => sys_chroot(args[..1]);
|
SYS_CHROOT = 161 => sys_chroot(args[..1]);
|
||||||
SYS_SYNC = 162 => sys_sync(args[..0]);
|
SYS_SYNC = 162 => sys_sync(args[..0]);
|
||||||
SYS_MOUNT = 165 => sys_mount(args[..5]);
|
SYS_MOUNT = 165 => sys_mount(args[..5]);
|
||||||
@ -297,8 +297,8 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_PWRITEV = 296 => sys_pwritev(args[..4]);
|
SYS_PWRITEV = 296 => sys_pwritev(args[..4]);
|
||||||
SYS_PRLIMIT64 = 302 => sys_prlimit64(args[..4]);
|
SYS_PRLIMIT64 = 302 => sys_prlimit64(args[..4]);
|
||||||
SYS_GETRANDOM = 318 => sys_getrandom(args[..3]);
|
SYS_GETRANDOM = 318 => sys_getrandom(args[..3]);
|
||||||
SYS_EXECVEAT = 322 => sys_execveat(args[..5], &mut context);
|
SYS_EXECVEAT = 322 => sys_execveat(args[..5], &mut user_ctx);
|
||||||
SYS_PREADV2 = 327 => sys_preadv2(args[..5]);
|
SYS_PREADV2 = 327 => sys_preadv2(args[..5]);
|
||||||
SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]);
|
SYS_PWRITEV2 = 328 => sys_pwritev2(args[..5]);
|
||||||
SYS_CLONE3 = 435 => sys_clone3(args[..2], &context);
|
SYS_CLONE3 = 435 => sys_clone3(args[..2], &user_ctx);
|
||||||
}
|
}
|
||||||
|
@ -15,23 +15,28 @@ pub enum ArchPrctlCode {
|
|||||||
ARCH_GET_GS = 0x1004,
|
ARCH_GET_GS = 0x1004,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_arch_prctl(code: u64, addr: u64, context: &mut UserContext) -> Result<SyscallReturn> {
|
pub fn sys_arch_prctl(
|
||||||
|
code: u64,
|
||||||
|
addr: u64,
|
||||||
|
_ctx: &Context,
|
||||||
|
user_ctx: &mut UserContext,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let arch_prctl_code = ArchPrctlCode::try_from(code)?;
|
let arch_prctl_code = ArchPrctlCode::try_from(code)?;
|
||||||
debug!(
|
debug!(
|
||||||
"arch_prctl_code: {:?}, addr = 0x{:x}",
|
"arch_prctl_code: {:?}, addr = 0x{:x}",
|
||||||
arch_prctl_code, addr
|
arch_prctl_code, addr
|
||||||
);
|
);
|
||||||
let res = do_arch_prctl(arch_prctl_code, addr, context).unwrap();
|
let res = do_arch_prctl(arch_prctl_code, addr, user_ctx).unwrap();
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, context: &mut UserContext) -> Result<u64> {
|
pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, ctx: &mut UserContext) -> Result<u64> {
|
||||||
match code {
|
match code {
|
||||||
ArchPrctlCode::ARCH_SET_FS => {
|
ArchPrctlCode::ARCH_SET_FS => {
|
||||||
context.set_tls_pointer(addr as usize);
|
ctx.set_tls_pointer(addr as usize);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
ArchPrctlCode::ARCH_GET_FS => Ok(context.tls_pointer() as u64),
|
ArchPrctlCode::ARCH_GET_FS => Ok(ctx.tls_pointer() as u64),
|
||||||
ArchPrctlCode::ARCH_GET_GS | ArchPrctlCode::ARCH_SET_GS => {
|
ArchPrctlCode::ARCH_GET_GS | ArchPrctlCode::ARCH_SET_GS => {
|
||||||
return_errno_with_message!(Errno::EINVAL, "GS cannot be accessed from the user space")
|
return_errno_with_message!(Errno::EINVAL, "GS cannot be accessed from the user space")
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, read_socket_addr_from_user},
|
util::net::{get_socket_from_fd, read_socket_addr_from_user},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_bind(sockfd: FileDesc, sockaddr_ptr: Vaddr, addrlen: u32) -> Result<SyscallReturn> {
|
pub fn sys_bind(
|
||||||
|
sockfd: FileDesc,
|
||||||
|
sockaddr_ptr: Vaddr,
|
||||||
|
addrlen: u32,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?;
|
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?;
|
||||||
debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}");
|
debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}");
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use crate::{prelude::*, syscall::SyscallReturn};
|
use crate::{prelude::*, syscall::SyscallReturn};
|
||||||
|
|
||||||
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
||||||
pub fn sys_brk(heap_end: u64) -> Result<SyscallReturn> {
|
pub fn sys_brk(heap_end: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let new_heap_end = if heap_end == 0 {
|
let new_heap_end = if heap_end == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,7 +9,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let cap_user_header: cap_user_header_t =
|
let cap_user_header: cap_user_header_t =
|
||||||
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
||||||
|
@ -16,7 +16,11 @@ fn make_kernel_cap(low: u32, high: u32) -> u64 {
|
|||||||
((low as u64) | ((high as u64) << 32)) & ((1u64 << (CapSet::most_significant_bit() + 1)) - 1)
|
((low as u64) | ((high as u64) << 32)) & ((1u64 << (CapSet::most_significant_bit() + 1)) - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let cap_user_header: cap_user_header_t =
|
let cap_user_header: cap_user_header_t =
|
||||||
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
user_space.read_val::<cap_user_header_t>(cap_user_header_addr)?;
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chdir(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_chdir(path_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ pub fn sys_chdir(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_fchdir(fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_fchdir(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_fchmod(fd: FileDesc, mode: u16, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, mode = 0o{:o}", fd, mode);
|
debug!("fd = {}, mode = 0o{:o}", fd, mode);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
@ -20,8 +20,8 @@ pub fn sys_fchmod(fd: FileDesc, mode: u16) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_chmod(path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_chmod(path_ptr: Vaddr, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_fchmodat(AT_FDCWD, path_ptr, mode)
|
self::sys_fchmodat(AT_FDCWD, path_ptr, mode, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glibc handles the `flags` argument, so we just ignore it.
|
// Glibc handles the `flags` argument, so we just ignore it.
|
||||||
@ -30,6 +30,7 @@ pub fn sys_fchmodat(
|
|||||||
path_ptr: Vaddr,
|
path_ptr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
/* flags: u32, */
|
/* flags: u32, */
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(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,);
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
process::{Gid, Uid},
|
process::{Gid, Uid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, uid = {}, gid = {}", fd, uid, gid);
|
debug!("fd = {}, uid = {}, gid = {}", fd, uid, gid);
|
||||||
|
|
||||||
let uid = to_optional_id(uid, Uid::new)?;
|
let uid = to_optional_id(uid, Uid::new)?;
|
||||||
@ -32,17 +32,18 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_chown(path_ptr: Vaddr, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
pub fn sys_chown(path_ptr: Vaddr, uid: i32, gid: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_fchownat(AT_FDCWD, path_ptr, uid, gid, 0)
|
self::sys_fchownat(AT_FDCWD, path_ptr, uid, gid, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_lchown(path_ptr: Vaddr, uid: i32, gid: i32) -> Result<SyscallReturn> {
|
pub fn sys_lchown(path_ptr: Vaddr, uid: i32, gid: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_fchownat(
|
self::sys_fchownat(
|
||||||
AT_FDCWD,
|
AT_FDCWD,
|
||||||
path_ptr,
|
path_ptr,
|
||||||
uid,
|
uid,
|
||||||
gid,
|
gid,
|
||||||
ChownFlags::AT_SYMLINK_NOFOLLOW.bits(),
|
ChownFlags::AT_SYMLINK_NOFOLLOW.bits(),
|
||||||
|
ctx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ pub fn sys_fchownat(
|
|||||||
uid: i32,
|
uid: i32,
|
||||||
gid: i32,
|
gid: i32,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(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)
|
||||||
@ -65,7 +67,7 @@ pub fn sys_fchownat(
|
|||||||
if !flags.contains(ChownFlags::AT_EMPTY_PATH) {
|
if !flags.contains(ChownFlags::AT_EMPTY_PATH) {
|
||||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||||
}
|
}
|
||||||
return self::sys_fchown(dirfd, uid, gid);
|
return self::sys_fchown(dirfd, uid, gid, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let uid = to_optional_id(uid, Uid::new)?;
|
let uid = to_optional_id(uid, Uid::new)?;
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_chroot(path_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_chroot(path_ptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
||||||
debug!("path = {:?}", path);
|
debug!("path = {:?}", path);
|
||||||
|
|
||||||
|
@ -19,7 +19,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_clock_gettime(clockid: clockid_t, timespec_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_clock_gettime(
|
||||||
|
clockid: clockid_t,
|
||||||
|
timespec_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("clockid = {:?}", clockid);
|
debug!("clockid = {:?}", clockid);
|
||||||
|
|
||||||
let time_duration = read_clock(clockid)?;
|
let time_duration = read_clock(clockid)?;
|
||||||
|
@ -16,18 +16,20 @@ pub fn sys_clone(
|
|||||||
parent_tidptr: Vaddr,
|
parent_tidptr: Vaddr,
|
||||||
child_tidptr: Vaddr,
|
child_tidptr: Vaddr,
|
||||||
tls: u64,
|
tls: u64,
|
||||||
|
ctx: &Context,
|
||||||
parent_context: &UserContext,
|
parent_context: &UserContext,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let clone_flags = CloneFlags::from(clone_flags);
|
let clone_flags = CloneFlags::from(clone_flags);
|
||||||
debug!("flags = {:?}, child_stack_ptr = 0x{:x}, parent_tid_ptr = 0x{:x}, child tid ptr = 0x{:x}, tls = 0x{:x}", clone_flags, new_sp, parent_tidptr, child_tidptr, tls);
|
debug!("flags = {:?}, child_stack_ptr = 0x{:x}, parent_tid_ptr = 0x{:x}, child tid ptr = 0x{:x}, tls = 0x{:x}", clone_flags, new_sp, parent_tidptr, child_tidptr, tls);
|
||||||
let clone_args = CloneArgs::new(new_sp, 0, parent_tidptr, child_tidptr, tls, clone_flags);
|
let clone_args = CloneArgs::new(new_sp, 0, parent_tidptr, child_tidptr, tls, clone_flags);
|
||||||
let child_pid = clone_child(parent_context, clone_args).unwrap();
|
let child_pid = clone_child(ctx, parent_context, clone_args).unwrap();
|
||||||
Ok(SyscallReturn::Return(child_pid as _))
|
Ok(SyscallReturn::Return(child_pid as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_clone3(
|
pub fn sys_clone3(
|
||||||
clong_args_addr: Vaddr,
|
clong_args_addr: Vaddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
|
ctx: &Context,
|
||||||
parent_context: &UserContext,
|
parent_context: &UserContext,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
trace!(
|
trace!(
|
||||||
@ -46,7 +48,7 @@ pub fn sys_clone3(
|
|||||||
};
|
};
|
||||||
debug!("clone args = {:x?}", clone_args);
|
debug!("clone args = {:x?}", clone_args);
|
||||||
|
|
||||||
let child_pid = clone_child(parent_context, clone_args)?;
|
let child_pid = clone_child(ctx, parent_context, clone_args)?;
|
||||||
trace!("child pid = {}", child_pid);
|
trace!("child pid = {}", child_pid);
|
||||||
Ok(SyscallReturn::Return(child_pid as _))
|
Ok(SyscallReturn::Return(child_pid as _))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{fs::file_table::FileDesc, prelude::*};
|
||||||
|
|
||||||
pub fn sys_close(fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_close(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
|
@ -7,7 +7,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, read_socket_addr_from_user},
|
util::net::{get_socket_from_fd, read_socket_addr_from_user},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_connect(sockfd: FileDesc, sockaddr_ptr: Vaddr, addr_len: u32) -> Result<SyscallReturn> {
|
pub fn sys_connect(
|
||||||
|
sockfd: FileDesc,
|
||||||
|
sockaddr_ptr: Vaddr,
|
||||||
|
addr_len: u32,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?;
|
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?;
|
||||||
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
|
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_dup(old_fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_dup(old_fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}", old_fd);
|
debug!("old_fd = {}", old_fd);
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
@ -17,7 +17,7 @@ pub fn sys_dup(old_fd: FileDesc) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||||
|
|
||||||
if old_fd == new_fd {
|
if old_fd == new_fd {
|
||||||
@ -30,7 +30,12 @@ pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<SyscallReturn> {
|
|||||||
do_dup3(old_fd, new_fd, FdFlags::empty())
|
do_dup3(old_fd, new_fd, FdFlags::empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_dup3(
|
||||||
|
old_fd: FileDesc,
|
||||||
|
new_fd: FileDesc,
|
||||||
|
flags: u32,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
|
||||||
|
|
||||||
let fdflag = match flags {
|
let fdflag = match flags {
|
||||||
|
@ -14,14 +14,14 @@ use crate::{
|
|||||||
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_epoll_create(size: i32) -> Result<SyscallReturn> {
|
pub fn sys_epoll_create(size: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "size is not positive");
|
return_errno_with_message!(Errno::EINVAL, "size is not positive");
|
||||||
}
|
}
|
||||||
sys_epoll_create1(0)
|
sys_epoll_create1(0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_epoll_create1(flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_epoll_create1(flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("flags = 0x{:x}", flags);
|
debug!("flags = 0x{:x}", flags);
|
||||||
|
|
||||||
let fd_flags = {
|
let fd_flags = {
|
||||||
@ -49,6 +49,7 @@ pub fn sys_epoll_ctl(
|
|||||||
op: i32,
|
op: i32,
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
event_addr: Vaddr,
|
event_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, op = {}, fd = {}, event_addr = 0x{:x}",
|
"epfd = {}, op = {}, fd = {}, event_addr = 0x{:x}",
|
||||||
@ -128,6 +129,7 @@ pub fn sys_epoll_wait(
|
|||||||
events_addr: Vaddr,
|
events_addr: Vaddr,
|
||||||
max_events: i32,
|
max_events: i32,
|
||||||
timeout: i32,
|
timeout: i32,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}",
|
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}",
|
||||||
@ -182,6 +184,7 @@ pub fn sys_epoll_pwait(
|
|||||||
timeout: i32,
|
timeout: i32,
|
||||||
sigmask: Vaddr,
|
sigmask: Vaddr,
|
||||||
sigset_size: usize,
|
sigset_size: usize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}, sigmask = 0x{:x}, sigset_size = {}",
|
"epfd = {}, events_addr = 0x{:x}, max_events = {}, timeout = {:?}, sigmask = 0x{:x}, sigset_size = {}",
|
||||||
|
@ -30,7 +30,7 @@ use crate::{
|
|||||||
time::clocks::RealTimeClock,
|
time::clocks::RealTimeClock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_eventfd(init_val: u64) -> Result<SyscallReturn> {
|
pub fn sys_eventfd(init_val: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("init_val = 0x{:x}", init_val);
|
debug!("init_val = 0x{:x}", init_val);
|
||||||
|
|
||||||
let fd = do_sys_eventfd2(init_val, Flags::empty());
|
let fd = do_sys_eventfd2(init_val, Flags::empty());
|
||||||
@ -38,7 +38,7 @@ pub fn sys_eventfd(init_val: u64) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_eventfd2(init_val: u64, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_eventfd2(init_val: u64, flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
trace!("raw flags = {}", flags);
|
trace!("raw flags = {}", flags);
|
||||||
let flags = Flags::from_bits(flags)
|
let flags = Flags::from_bits(flags)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown flags"))?;
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown flags"))?;
|
||||||
|
@ -14,8 +14,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
check_executable_file, credentials_mut, load_program_to_vm,
|
check_executable_file, credentials_mut, load_program_to_vm, posix_thread::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,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -24,14 +23,15 @@ pub fn sys_execve(
|
|||||||
filename_ptr: Vaddr,
|
filename_ptr: Vaddr,
|
||||||
argv_ptr_ptr: Vaddr,
|
argv_ptr_ptr: Vaddr,
|
||||||
envp_ptr_ptr: Vaddr,
|
envp_ptr_ptr: Vaddr,
|
||||||
context: &mut UserContext,
|
ctx: &Context,
|
||||||
|
user_ctx: &mut UserContext,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let elf_file = {
|
let elf_file = {
|
||||||
let executable_path = read_filename(filename_ptr)?;
|
let executable_path = read_filename(filename_ptr)?;
|
||||||
lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty())?
|
lookup_executable_file(AT_FDCWD, executable_path, OpenFlags::empty())?
|
||||||
};
|
};
|
||||||
|
|
||||||
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?;
|
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
||||||
Ok(SyscallReturn::NoReturn)
|
Ok(SyscallReturn::NoReturn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,8 @@ pub fn sys_execveat(
|
|||||||
argv_ptr_ptr: Vaddr,
|
argv_ptr_ptr: Vaddr,
|
||||||
envp_ptr_ptr: Vaddr,
|
envp_ptr_ptr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
context: &mut UserContext,
|
ctx: &Context,
|
||||||
|
user_ctx: &mut UserContext,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let elf_file = {
|
let elf_file = {
|
||||||
let flags = OpenFlags::from_bits_truncate(flags);
|
let flags = OpenFlags::from_bits_truncate(flags);
|
||||||
@ -49,7 +50,7 @@ pub fn sys_execveat(
|
|||||||
lookup_executable_file(dfd, filename, flags)?
|
lookup_executable_file(dfd, filename, flags)?
|
||||||
};
|
};
|
||||||
|
|
||||||
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, context)?;
|
do_execve(elf_file, argv_ptr_ptr, envp_ptr_ptr, ctx, user_ctx)?;
|
||||||
Ok(SyscallReturn::NoReturn)
|
Ok(SyscallReturn::NoReturn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +83,16 @@ fn do_execve(
|
|||||||
elf_file: Arc<Dentry>,
|
elf_file: Arc<Dentry>,
|
||||||
argv_ptr_ptr: Vaddr,
|
argv_ptr_ptr: Vaddr,
|
||||||
envp_ptr_ptr: Vaddr,
|
envp_ptr_ptr: Vaddr,
|
||||||
context: &mut UserContext,
|
ctx: &Context,
|
||||||
|
user_ctx: &mut UserContext,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let Context {
|
||||||
|
process,
|
||||||
|
posix_thread,
|
||||||
|
thread: _,
|
||||||
|
task: _,
|
||||||
|
} = ctx;
|
||||||
|
|
||||||
let executable_path = elf_file.abs_path();
|
let executable_path = elf_file.abs_path();
|
||||||
let argv = read_cstring_vec(argv_ptr_ptr, MAX_ARGV_NUMBER, MAX_ARG_LEN)?;
|
let argv = read_cstring_vec(argv_ptr_ptr, MAX_ARGV_NUMBER, MAX_ARG_LEN)?;
|
||||||
let envp = read_cstring_vec(envp_ptr_ptr, MAX_ENVP_NUMBER, MAX_ENV_LEN)?;
|
let envp = read_cstring_vec(envp_ptr_ptr, MAX_ENVP_NUMBER, MAX_ENV_LEN)?;
|
||||||
@ -92,24 +101,20 @@ fn do_execve(
|
|||||||
executable_path, argv, envp
|
executable_path, argv, envp
|
||||||
);
|
);
|
||||||
// FIXME: should we set thread name in execve?
|
// FIXME: should we set thread name in execve?
|
||||||
let current_thread = current_thread!();
|
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
*posix_thread.thread_name().lock() =
|
*posix_thread.thread_name().lock() =
|
||||||
Some(ThreadName::new_from_executable_path(&executable_path)?);
|
Some(ThreadName::new_from_executable_path(&executable_path)?);
|
||||||
// clear ctid
|
// clear ctid
|
||||||
// FIXME: should we clear ctid when execve?
|
// FIXME: should we clear ctid when execve?
|
||||||
*posix_thread.clear_child_tid().lock() = 0;
|
*posix_thread.clear_child_tid().lock() = 0;
|
||||||
|
|
||||||
let current = current!();
|
|
||||||
|
|
||||||
// Ensure that the file descriptors with the close-on-exec flag are closed.
|
// Ensure that the file descriptors with the close-on-exec flag are closed.
|
||||||
let closed_files = current.file_table().lock().close_files_on_exec();
|
let closed_files = process.file_table().lock().close_files_on_exec();
|
||||||
drop(closed_files);
|
drop(closed_files);
|
||||||
|
|
||||||
debug!("load program to root vmar");
|
debug!("load program to root vmar");
|
||||||
let (new_executable_path, elf_load_info) = {
|
let (new_executable_path, elf_load_info) = {
|
||||||
let fs_resolver = &*current.fs().read();
|
let fs_resolver = &*process.fs().read();
|
||||||
let process_vm = current.vm();
|
let process_vm = process.vm();
|
||||||
load_program_to_vm(process_vm, elf_file.clone(), argv, envp, fs_resolver, 1)?
|
load_program_to_vm(process_vm, elf_file.clone(), argv, envp, fs_resolver, 1)?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,23 +124,23 @@ fn do_execve(
|
|||||||
debug!("load elf in execve succeeds");
|
debug!("load elf in execve succeeds");
|
||||||
|
|
||||||
let credentials = credentials_mut();
|
let credentials = credentials_mut();
|
||||||
set_uid_from_elf(¤t, &credentials, &elf_file)?;
|
set_uid_from_elf(process, &credentials, &elf_file)?;
|
||||||
set_gid_from_elf(¤t, &credentials, &elf_file)?;
|
set_gid_from_elf(process, &credentials, &elf_file)?;
|
||||||
|
|
||||||
// set executable path
|
// set executable path
|
||||||
current.set_executable_path(new_executable_path);
|
process.set_executable_path(new_executable_path);
|
||||||
// set signal disposition to default
|
// set signal disposition to default
|
||||||
current.sig_dispositions().lock().inherit();
|
process.sig_dispositions().lock().inherit();
|
||||||
// set cpu context to default
|
// set cpu ctx to default
|
||||||
let default_content = UserContext::default();
|
let default_content = UserContext::default();
|
||||||
*context.general_regs_mut() = *default_content.general_regs();
|
*user_ctx.general_regs_mut() = *default_content.general_regs();
|
||||||
context.set_tls_pointer(default_content.tls_pointer());
|
user_ctx.set_tls_pointer(default_content.tls_pointer());
|
||||||
*context.fp_regs_mut() = *default_content.fp_regs();
|
*user_ctx.fp_regs_mut() = *default_content.fp_regs();
|
||||||
// set new entry point
|
// set new entry point
|
||||||
context.set_instruction_pointer(elf_load_info.entry_point() as _);
|
user_ctx.set_instruction_pointer(elf_load_info.entry_point() as _);
|
||||||
debug!("entry_point: 0x{:x}", elf_load_info.entry_point());
|
debug!("entry_point: 0x{:x}", elf_load_info.entry_point());
|
||||||
// set new user stack top
|
// set new user stack top
|
||||||
context.set_stack_pointer(elf_load_info.user_stack_top() as _);
|
user_ctx.set_stack_pointer(elf_load_info.user_stack_top() as _);
|
||||||
debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top());
|
debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -184,7 +189,7 @@ fn read_cstring_vec(
|
|||||||
|
|
||||||
/// Sets uid for credentials as the same of uid of elf file if elf file has `set_uid` bit.
|
/// Sets uid for credentials as the same of uid of elf file if elf file has `set_uid` bit.
|
||||||
fn set_uid_from_elf(
|
fn set_uid_from_elf(
|
||||||
current: &Arc<Process>,
|
current: &Process,
|
||||||
credentials: &Credentials<WriteOp>,
|
credentials: &Credentials<WriteOp>,
|
||||||
elf_file: &Arc<Dentry>,
|
elf_file: &Arc<Dentry>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -202,7 +207,7 @@ fn set_uid_from_elf(
|
|||||||
|
|
||||||
/// Sets gid for credentials as the same of gid of elf file if elf file has `set_gid` bit.
|
/// Sets gid for credentials as the same of gid of elf file if elf file has `set_gid` bit.
|
||||||
fn set_gid_from_elf(
|
fn set_gid_from_elf(
|
||||||
current: &Arc<Process>,
|
current: &Process,
|
||||||
credentials: &Credentials<WriteOp>,
|
credentials: &Credentials<WriteOp>,
|
||||||
elf_file: &Arc<Dentry>,
|
elf_file: &Arc<Dentry>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
syscall::SyscallReturn,
|
syscall::SyscallReturn,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_exit(exit_code: i32) -> Result<SyscallReturn> {
|
pub fn sys_exit(exit_code: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("exid code = {}", exit_code);
|
debug!("exid code = {}", exit_code);
|
||||||
|
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Exit all thread in a process.
|
/// Exit all thread in a process.
|
||||||
pub fn sys_exit_group(exit_code: u64) -> Result<SyscallReturn> {
|
pub fn sys_exit_group(exit_code: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
// Exit all thread in current process
|
// Exit all thread in current process
|
||||||
let term_status = TermStatus::Exited(exit_code as _);
|
let term_status = TermStatus::Exited(exit_code as _);
|
||||||
do_exit_group(term_status);
|
do_exit_group(term_status);
|
||||||
|
@ -7,7 +7,13 @@ use crate::{
|
|||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fallocate(fd: FileDesc, mode: u64, offset: i64, len: i64) -> Result<SyscallReturn> {
|
pub fn sys_fallocate(
|
||||||
|
fd: FileDesc,
|
||||||
|
mode: u64,
|
||||||
|
offset: i64,
|
||||||
|
len: i64,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, mode = {}, offset = {}, len = {}",
|
"fd = {}, mode = {}, offset = {}, len = {}",
|
||||||
fd, mode, offset, len
|
fd, mode, offset, len
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
process::Pid,
|
process::Pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64) -> Result<SyscallReturn> {
|
pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let fcntl_cmd = FcntlCmd::try_from(cmd)?;
|
let fcntl_cmd = FcntlCmd::try_from(cmd)?;
|
||||||
debug!("fd = {}, cmd = {:?}, arg = {}", fd, fcntl_cmd, arg);
|
debug!("fd = {}, cmd = {:?}, arg = {}", fd, fcntl_cmd, arg);
|
||||||
match fcntl_cmd {
|
match fcntl_cmd {
|
||||||
|
@ -8,8 +8,8 @@ use crate::{
|
|||||||
process::{clone_child, CloneArgs},
|
process::{clone_child, CloneArgs},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fork(parent_context: &UserContext) -> Result<SyscallReturn> {
|
pub fn sys_fork(ctx: &Context, parent_context: &UserContext) -> Result<SyscallReturn> {
|
||||||
let clone_args = CloneArgs::for_fork();
|
let clone_args = CloneArgs::for_fork();
|
||||||
let child_pid = clone_child(parent_context, clone_args).unwrap();
|
let child_pid = clone_child(ctx, parent_context, clone_args).unwrap();
|
||||||
Ok(SyscallReturn::Return(child_pid as _))
|
Ok(SyscallReturn::Return(child_pid as _))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_fsync(fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_fsync(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
@ -22,7 +22,7 @@ pub fn sys_fsync(fd: FileDesc) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_fdatasync(fd: FileDesc) -> Result<SyscallReturn> {
|
pub fn sys_fdatasync(fd: FileDesc, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
|
@ -16,6 +16,7 @@ pub fn sys_futex(
|
|||||||
utime_addr: u64,
|
utime_addr: u64,
|
||||||
futex_new_addr: u64,
|
futex_new_addr: u64,
|
||||||
bitset: u64,
|
bitset: u64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
// FIXME: we current ignore futex flags
|
// FIXME: we current ignore futex flags
|
||||||
let (futex_op, futex_flags) = futex_op_and_flags_from_u32(futex_op as _).unwrap();
|
let (futex_op, futex_flags) = futex_op_and_flags_from_u32(futex_op as _).unwrap();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getcwd(buf: Vaddr, len: usize) -> Result<SyscallReturn> {
|
pub fn sys_getcwd(buf: Vaddr, len: usize, _ctx: &Context) -> 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();
|
||||||
|
@ -12,7 +12,12 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
fd, buf_addr, buf_len
|
fd, buf_addr, buf_len
|
||||||
@ -37,7 +42,12 @@ pub fn sys_getdents(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<Sys
|
|||||||
Ok(SyscallReturn::Return(read_len as _))
|
Ok(SyscallReturn::Return(read_len as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_getdents64(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<SyscallReturn> {
|
pub fn sys_getdents64(
|
||||||
|
fd: FileDesc,
|
||||||
|
buf_addr: Vaddr,
|
||||||
|
buf_len: usize,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, buf_addr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
fd, buf_addr, buf_len
|
fd, buf_addr, buf_len
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getegid() -> Result<SyscallReturn> {
|
pub fn sys_getegid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let egid = {
|
let egid = {
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
credentials.egid()
|
credentials.egid()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_geteuid() -> Result<SyscallReturn> {
|
pub fn sys_geteuid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let euid = {
|
let euid = {
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
credentials.euid()
|
credentials.euid()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getgid() -> Result<SyscallReturn> {
|
pub fn sys_getgid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let gid = {
|
let gid = {
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
credentials.rgid()
|
credentials.rgid()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
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, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
|
debug!("size = {}, group_list_addr = 0x{:x}", size, group_list_addr);
|
||||||
|
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
|
@ -7,7 +7,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, write_socket_addr_to_user},
|
util::net::{get_socket_from_fd, write_socket_addr_to_user},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getpeername(sockfd: FileDesc, addr: Vaddr, addrlen_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getpeername(
|
||||||
|
sockfd: FileDesc,
|
||||||
|
addr: Vaddr,
|
||||||
|
addrlen_ptr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
||||||
|
|
||||||
let peer_addr = {
|
let peer_addr = {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getpgrp() -> Result<SyscallReturn> {
|
pub fn sys_getpgrp(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
Ok(SyscallReturn::Return(current.pgid() as _))
|
Ok(SyscallReturn::Return(current.pgid() as _))
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getpid() -> Result<SyscallReturn> {
|
pub fn sys_getpid(ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let pid = current!().pid();
|
let pid = ctx.process.pid();
|
||||||
debug!("[sys_getpid]: pid = {}", pid);
|
debug!("[sys_getpid]: pid = {}", pid);
|
||||||
Ok(SyscallReturn::Return(pid as _))
|
Ok(SyscallReturn::Return(pid as _))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_getppid() -> Result<SyscallReturn> {
|
pub fn sys_getppid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let parent = current.parent();
|
let parent = current.parent();
|
||||||
match parent {
|
match parent {
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{device, prelude::*};
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let flags = GetRandomFlags::from_bits_truncate(flags);
|
let flags = GetRandomFlags::from_bits_truncate(flags);
|
||||||
debug!(
|
debug!(
|
||||||
"buf = 0x{:x}, count = 0x{:x}, flags = {:?}",
|
"buf = 0x{:x}, count = 0x{:x}, flags = {:?}",
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> 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();
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> 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();
|
||||||
|
@ -14,7 +14,7 @@ enum RusageTarget {
|
|||||||
Thread = 1,
|
Thread = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_getrusage(target: i32, rusage_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getrusage(target: i32, rusage_addr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let rusage_target = RusageTarget::try_from(target)?;
|
let rusage_target = RusageTarget::try_from(target)?;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
@ -86,7 +86,7 @@ pub struct rusage_t {
|
|||||||
pub ru_msgrcv: u64,
|
pub ru_msgrcv: u64,
|
||||||
/// signals received
|
/// signals received
|
||||||
pub ru_nsignals: u64,
|
pub ru_nsignals: u64,
|
||||||
/// voluntary context switches
|
/// voluntary ctx switches
|
||||||
pub ru_nvcsw: u64,
|
pub ru_nvcsw: u64,
|
||||||
/// involuntary
|
/// involuntary
|
||||||
pub ru_nivcsw: u64,
|
pub ru_nivcsw: u64,
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
process::{process_table, Pid},
|
process::{process_table, Pid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getsid(pid: Pid) -> Result<SyscallReturn> {
|
pub fn sys_getsid(pid: Pid, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("pid = {}", pid);
|
debug!("pid = {}", pid);
|
||||||
|
|
||||||
let session = current!().session().unwrap();
|
let session = current!().session().unwrap();
|
||||||
|
@ -7,7 +7,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, write_socket_addr_to_user},
|
util::net::{get_socket_from_fd, write_socket_addr_to_user},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_getsockname(sockfd: FileDesc, addr: Vaddr, addrlen_ptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_getsockname(
|
||||||
|
sockfd: FileDesc,
|
||||||
|
addr: Vaddr,
|
||||||
|
addrlen_ptr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
||||||
|
|
||||||
let socket_addr = {
|
let socket_addr = {
|
||||||
|
@ -13,6 +13,7 @@ pub fn sys_getsockopt(
|
|||||||
optname: i32,
|
optname: i32,
|
||||||
optval: Vaddr,
|
optval: Vaddr,
|
||||||
optlen_addr: Vaddr,
|
optlen_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let level = CSocketOptionLevel::try_from(level)?;
|
let level = CSocketOptionLevel::try_from(level)?;
|
||||||
if optval == 0 || optlen_addr == 0 {
|
if optval == 0 || optlen_addr == 0 {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_gettid() -> Result<SyscallReturn> {
|
pub fn sys_gettid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
let tid = current_thread.tid();
|
let tid = current_thread.tid();
|
||||||
Ok(SyscallReturn::Return(tid as _))
|
Ok(SyscallReturn::Return(tid as _))
|
||||||
|
@ -8,7 +8,10 @@ use crate::{
|
|||||||
|
|
||||||
// The use of the timezone structure is obsolete.
|
// The use of the timezone structure is obsolete.
|
||||||
// Glibc sets the timezone_addr argument to NULL, so just ignore it.
|
// Glibc sets the timezone_addr argument to NULL, so just ignore it.
|
||||||
pub fn sys_gettimeofday(timeval_addr: Vaddr, /* timezone_addr: Vaddr */) -> Result<SyscallReturn> {
|
pub fn sys_gettimeofday(
|
||||||
|
timeval_addr: Vaddr,
|
||||||
|
/* timezone_addr: Vaddr */ _ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
if timeval_addr == 0 {
|
if timeval_addr == 0 {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::credentials};
|
use crate::{prelude::*, process::credentials};
|
||||||
|
|
||||||
pub fn sys_getuid() -> Result<SyscallReturn> {
|
pub fn sys_getuid(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let uid = {
|
let uid = {
|
||||||
let credentials = credentials();
|
let credentials = credentials();
|
||||||
credentials.ruid()
|
credentials.ruid()
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let ioctl_cmd = IoctlCmd::try_from(cmd)?;
|
let ioctl_cmd = IoctlCmd::try_from(cmd)?;
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, ioctl_cmd = {:?}, arg = 0x{:x}",
|
"fd = {}, ioctl_cmd = {:?}, arg = 0x{:x}",
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result<SyscallReturn> {
|
pub fn sys_kill(process_filter: u64, sig_num: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let process_filter = ProcessFilter::from_id(process_filter as _);
|
let process_filter = ProcessFilter::from_id(process_filter as _);
|
||||||
let sig_num = if sig_num == 0 {
|
let sig_num = if sig_num == 0 {
|
||||||
None
|
None
|
||||||
|
@ -16,6 +16,7 @@ pub fn sys_linkat(
|
|||||||
new_dirfd: FileDesc,
|
new_dirfd: FileDesc,
|
||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
|
|
||||||
@ -58,8 +59,12 @@ pub fn sys_linkat(
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_link(old_path_addr: Vaddr, new_path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_link(
|
||||||
self::sys_linkat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, 0)
|
old_path_addr: Vaddr,
|
||||||
|
new_path_addr: Vaddr,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
self::sys_linkat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::net::get_socket_from_fd};
|
use crate::{fs::file_table::FileDesc, prelude::*, util::net::get_socket_from_fd};
|
||||||
|
|
||||||
pub fn sys_listen(sockfd: FileDesc, backlog: i32) -> Result<SyscallReturn> {
|
pub fn sys_listen(sockfd: FileDesc, backlog: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("sockfd = {sockfd}, backlog = {backlog}");
|
debug!("sockfd = {sockfd}, backlog = {backlog}");
|
||||||
|
|
||||||
let socket = get_socket_from_fd(sockfd)?;
|
let socket = get_socket_from_fd(sockfd)?;
|
||||||
|
@ -6,7 +6,12 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_lseek(fd: FileDesc, offset: isize, whence: u32) -> Result<SyscallReturn> {
|
pub fn sys_lseek(
|
||||||
|
fd: FileDesc,
|
||||||
|
offset: isize,
|
||||||
|
whence: u32,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
||||||
let seek_from = match whence {
|
let seek_from = match whence {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let behavior = MadviseBehavior::try_from(behavior)?;
|
let behavior = MadviseBehavior::try_from(behavior)?;
|
||||||
debug!(
|
debug!(
|
||||||
"start = 0x{:x}, len = 0x{:x}, behavior = {:?}",
|
"start = 0x{:x}, len = 0x{:x}, behavior = {:?}",
|
||||||
|
@ -11,7 +11,12 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_mkdirat(
|
||||||
|
dirfd: FileDesc,
|
||||||
|
path_addr: Vaddr,
|
||||||
|
mode: u16,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(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);
|
||||||
|
|
||||||
@ -36,6 +41,6 @@ pub fn sys_mkdirat(dirfd: FileDesc, path_addr: Vaddr, mode: u16) -> Result<Sysca
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_mkdir(path_addr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_mkdir(path_addr: Vaddr, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_mkdirat(AT_FDCWD, path_addr, mode)
|
self::sys_mkdirat(AT_FDCWD, path_addr, mode, ctx)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ pub fn sys_mknodat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
dev: usize,
|
dev: usize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
let current = current!();
|
let current = current!();
|
||||||
@ -59,6 +60,6 @@ pub fn sys_mknodat(
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_mknod(path_addr: Vaddr, mode: u16, dev: usize) -> Result<SyscallReturn> {
|
pub fn sys_mknod(path_addr: Vaddr, mode: u16, dev: usize, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_mknodat(AT_FDCWD, path_addr, mode, dev)
|
self::sys_mknodat(AT_FDCWD, path_addr, mode, dev, ctx)
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ pub fn sys_mmap(
|
|||||||
flags: u64,
|
flags: u64,
|
||||||
fd: u64,
|
fd: u64,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let perms = VmPerms::from_posix_prot_bits(perms as u32).unwrap();
|
let perms = VmPerms::from_posix_prot_bits(perms as u32).unwrap();
|
||||||
let option = MMapOptions::try_from(flags as u32)?;
|
let option = MMapOptions::try_from(flags as u32)?;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
//! Read the Cpu context content then dispatch syscall to corrsponding handler
|
//! Read the Cpu ctx content then dispatch syscall to corrsponding handler
|
||||||
//! The each sub module contains functions that handle real syscall logic.
|
//! The each sub module contains functions that handle real syscall logic.
|
||||||
pub use clock_gettime::ClockId;
|
pub use clock_gettime::ClockId;
|
||||||
use ostd::cpu::UserContext;
|
use ostd::cpu::UserContext;
|
||||||
|
|
||||||
use crate::{cpu::LinuxAbi, prelude::*};
|
use crate::{context::Context, cpu::LinuxAbi, prelude::*};
|
||||||
|
|
||||||
mod accept;
|
mod accept;
|
||||||
mod access;
|
mod access;
|
||||||
@ -139,40 +139,119 @@ mod write;
|
|||||||
/// The first param is ths number of parameters,
|
/// The first param is ths number of parameters,
|
||||||
/// The second param is the function name of syscall handler,
|
/// The second param is the function name of syscall handler,
|
||||||
/// The third is optional, means the args(if parameter number > 0),
|
/// The third is optional, means the args(if parameter number > 0),
|
||||||
/// The third is optional, means if cpu context is required.
|
/// The third is optional, means if cpu ctx is required.
|
||||||
macro_rules! syscall_handler {
|
macro_rules! syscall_handler {
|
||||||
(0, $fn_name: ident, $args: ident) => { $fn_name() };
|
(0, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
(0, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($context) };
|
$fn_name($ctx)
|
||||||
(1, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _) };
|
};
|
||||||
(1, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $context) };
|
(0, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
(2, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _)};
|
$fn_name($ctx, $user_ctx)
|
||||||
(2, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $context)};
|
};
|
||||||
(3, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _)};
|
|
||||||
(3, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $context)};
|
(1, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
(4, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _)};
|
$fn_name($args[0] as _, $ctx)
|
||||||
(4, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _), $context};
|
};
|
||||||
(5, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _)};
|
(1, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
(5, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $context)};
|
$fn_name($args[0] as _, $ctx, $user_ctx)
|
||||||
(6, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _)};
|
};
|
||||||
(6, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _, $context)};
|
|
||||||
|
(2, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
|
$fn_name($args[0] as _, $args[1] as _, $ctx)
|
||||||
|
};
|
||||||
|
(2, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
|
$fn_name($args[0] as _, $args[1] as _, $ctx, $user_ctx)
|
||||||
|
};
|
||||||
|
|
||||||
|
(3, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
|
$fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx)
|
||||||
|
};
|
||||||
|
(3, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
|
$fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx, $user_ctx)
|
||||||
|
};
|
||||||
|
|
||||||
|
(4, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
(4, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$ctx,
|
||||||
|
$user_ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(5, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$args[4] as _,
|
||||||
|
$ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
(5, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$args[4] as _,
|
||||||
|
$ctx,
|
||||||
|
$user_ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(6, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$args[4] as _,
|
||||||
|
$args[5] as _,
|
||||||
|
$ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
(6, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||||
|
$fn_name(
|
||||||
|
$args[0] as _,
|
||||||
|
$args[1] as _,
|
||||||
|
$args[2] as _,
|
||||||
|
$args[3] as _,
|
||||||
|
$args[4] as _,
|
||||||
|
$args[5] as _,
|
||||||
|
$ctx,
|
||||||
|
$user_ctx,
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! dispatch_fn_inner {
|
macro_rules! dispatch_fn_inner {
|
||||||
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => {
|
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => {
|
||||||
$crate::syscall::syscall_handler!($cnt, $handler, $args)
|
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx)
|
||||||
};
|
};
|
||||||
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &context ) ) => {
|
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &user_ctx ) ) => {
|
||||||
$crate::syscall::syscall_handler!($cnt, $handler, $args, &$context)
|
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, &$user_ctx)
|
||||||
};
|
};
|
||||||
( $args: ident, $context: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut context ) ) => {
|
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut user_ctx ) ) => {
|
||||||
// `$context` is already of type `&mut ostd::cpu::UserContext`,
|
// `$user_ctx` is already of type `&mut ostd::cpu::UserContext`,
|
||||||
// so no need to take `&mut` again
|
// so no need to take `&mut` again
|
||||||
$crate::syscall::syscall_handler!($cnt, $handler, $args, $context)
|
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, $user_ctx)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_syscall_nums_and_dispatch_fn {
|
macro_rules! impl_syscall_nums_and_dispatch_fn {
|
||||||
// $args, $context, and $dispatcher_name are needed since Rust macro is hygienic
|
// $args, $user_ctx, and $dispatcher_name are needed since Rust macro is hygienic
|
||||||
( $( $name: ident = $num: literal => $handler: ident $args: tt );* $(;)? ) => {
|
( $( $name: ident = $num: literal => $handler: ident $args: tt );* $(;)? ) => {
|
||||||
// First, define the syscall numbers
|
// First, define the syscall numbers
|
||||||
$(
|
$(
|
||||||
@ -183,13 +262,14 @@ macro_rules! impl_syscall_nums_and_dispatch_fn {
|
|||||||
pub fn syscall_dispatch(
|
pub fn syscall_dispatch(
|
||||||
syscall_number: u64,
|
syscall_number: u64,
|
||||||
args: [u64; 6],
|
args: [u64; 6],
|
||||||
context: &mut ostd::cpu::UserContext,
|
ctx: &crate::context::Context,
|
||||||
|
user_ctx: &mut ostd::cpu::UserContext,
|
||||||
) -> $crate::prelude::Result<$crate::syscall::SyscallReturn> {
|
) -> $crate::prelude::Result<$crate::syscall::SyscallReturn> {
|
||||||
match syscall_number {
|
match syscall_number {
|
||||||
$(
|
$(
|
||||||
$num => {
|
$num => {
|
||||||
$crate::log_syscall_entry!($name);
|
$crate::log_syscall_entry!($name);
|
||||||
$crate::syscall::dispatch_fn_inner!(args, context, $handler $args)
|
$crate::syscall::dispatch_fn_inner!(args, ctx, user_ctx, $handler $args)
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
_ => {
|
_ => {
|
||||||
@ -221,9 +301,9 @@ pub enum SyscallReturn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SyscallArgument {
|
impl SyscallArgument {
|
||||||
fn new_from_context(context: &UserContext) -> Self {
|
fn new_from_context(user_ctx: &UserContext) -> Self {
|
||||||
let syscall_number = context.syscall_num() as u64;
|
let syscall_number = user_ctx.syscall_num() as u64;
|
||||||
let args = context.syscall_args().map(|x| x as u64);
|
let args = user_ctx.syscall_args().map(|x| x as u64);
|
||||||
Self {
|
Self {
|
||||||
syscall_number,
|
syscall_number,
|
||||||
args,
|
args,
|
||||||
@ -231,21 +311,25 @@ impl SyscallArgument {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_syscall(context: &mut UserContext) {
|
pub fn handle_syscall(ctx: &Context, user_ctx: &mut UserContext) {
|
||||||
let syscall_frame = SyscallArgument::new_from_context(context);
|
let syscall_frame = SyscallArgument::new_from_context(user_ctx);
|
||||||
let syscall_return =
|
let syscall_return = arch::syscall_dispatch(
|
||||||
arch::syscall_dispatch(syscall_frame.syscall_number, syscall_frame.args, context);
|
syscall_frame.syscall_number,
|
||||||
|
syscall_frame.args,
|
||||||
|
ctx,
|
||||||
|
user_ctx,
|
||||||
|
);
|
||||||
|
|
||||||
match syscall_return {
|
match syscall_return {
|
||||||
Ok(return_value) => {
|
Ok(return_value) => {
|
||||||
if let SyscallReturn::Return(return_value) = return_value {
|
if let SyscallReturn::Return(return_value) = return_value {
|
||||||
context.set_syscall_ret(return_value as usize);
|
user_ctx.set_syscall_ret(return_value as usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
debug!("syscall return error: {:?}", err);
|
debug!("syscall return error: {:?}", err);
|
||||||
let errno = err.error() as i32;
|
let errno = err.error() as i32;
|
||||||
context.set_syscall_ret((-errno) as usize)
|
user_ctx.set_syscall_ret((-errno) as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ pub fn sys_mount(
|
|||||||
fstype_addr: Vaddr,
|
fstype_addr: Vaddr,
|
||||||
flags: u64,
|
flags: u64,
|
||||||
data: Vaddr,
|
data: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
|
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
|
||||||
|
@ -5,7 +5,7 @@ use align_ext::AlignExt;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, vm::perms::VmPerms};
|
use crate::{prelude::*, vm::perms::VmPerms};
|
||||||
|
|
||||||
pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64) -> Result<SyscallReturn> {
|
pub fn sys_mprotect(addr: Vaddr, len: usize, perms: u64, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let vm_perms = VmPerms::from_bits_truncate(perms as u32);
|
let vm_perms = VmPerms::from_bits_truncate(perms as u32);
|
||||||
debug!(
|
debug!(
|
||||||
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}",
|
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}",
|
||||||
|
@ -5,7 +5,7 @@ use align_ext::AlignExt;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn sys_munmap(addr: Vaddr, len: usize) -> Result<SyscallReturn> {
|
pub fn sys_munmap(addr: Vaddr, len: usize, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("addr = 0x{:x}, len = {}", addr, len);
|
debug!("addr = 0x{:x}, len = {}", addr, len);
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let root_vmar = current.root_vmar();
|
let root_vmar = current.root_vmar();
|
||||||
|
@ -12,6 +12,7 @@ use crate::{
|
|||||||
pub fn sys_nanosleep(
|
pub fn sys_nanosleep(
|
||||||
request_timespec_addr: Vaddr,
|
request_timespec_addr: Vaddr,
|
||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let clockid = ClockId::CLOCK_MONOTONIC;
|
let clockid = ClockId::CLOCK_MONOTONIC;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ pub fn sys_clock_nanosleep(
|
|||||||
flags: i32,
|
flags: i32,
|
||||||
request_timespec_addr: Vaddr,
|
request_timespec_addr: Vaddr,
|
||||||
remain_timespec_addr: Vaddr,
|
remain_timespec_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let is_abs_time = if flags == 0 {
|
let is_abs_time = if flags == 0 {
|
||||||
false
|
false
|
||||||
|
@ -16,6 +16,7 @@ pub fn sys_openat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
mode: u16,
|
mode: u16,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = CurrentUserSpace::get().read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
debug!(
|
debug!(
|
||||||
@ -44,12 +45,12 @@ pub fn sys_openat(
|
|||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_open(path_addr: Vaddr, flags: u32, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_open(path_addr: Vaddr, flags: u32, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_openat(AT_FDCWD, path_addr, flags, mode)
|
self::sys_openat(AT_FDCWD, path_addr, flags, mode, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_creat(path_addr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
pub fn sys_creat(path_addr: Vaddr, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let flags =
|
let flags =
|
||||||
AccessMode::O_WRONLY as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits();
|
AccessMode::O_WRONLY as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits();
|
||||||
self::sys_openat(AT_FDCWD, path_addr, flags, mode)
|
self::sys_openat(AT_FDCWD, path_addr, flags, mode, ctx)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::signal::Pauser};
|
use crate::{prelude::*, process::signal::Pauser};
|
||||||
|
|
||||||
pub fn sys_pause() -> Result<SyscallReturn> {
|
pub fn sys_pause(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
// FIXME: like sleep, paused thread can only be interrupted by signals that will call signal
|
// FIXME: like sleep, paused thread can only be interrupted by signals that will call signal
|
||||||
// handler or terminate current process
|
// handler or terminate current process
|
||||||
let pauser = Pauser::new();
|
let pauser = Pauser::new();
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
pub fn sys_pipe2(fds: Vaddr, flags: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("flags: {:?}", flags);
|
debug!("flags: {:?}", flags);
|
||||||
|
|
||||||
let (pipe_reader, pipe_writer) = {
|
let (pipe_reader, pipe_writer) = {
|
||||||
@ -48,8 +48,8 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32) -> Result<SyscallReturn> {
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_pipe(fds: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_pipe(fds: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_pipe2(fds, 0)
|
self::sys_pipe2(fds, 0, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
|
@ -5,7 +5,7 @@ use core::{cell::Cell, time::Duration};
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller};
|
use crate::{events::IoEvents, fs::file_table::FileDesc, prelude::*, process::signal::Poller};
|
||||||
|
|
||||||
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32) -> Result<SyscallReturn> {
|
pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let poll_fds = {
|
let poll_fds = {
|
||||||
let mut read_addr = fds;
|
let mut read_addr = fds;
|
||||||
|
@ -9,7 +9,14 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let prctl_cmd = PrctlCmd::from_args(option, arg2, arg3, arg4, arg5)?;
|
let prctl_cmd = PrctlCmd::from_args(option, arg2, arg3, arg4, arg5)?;
|
||||||
debug!("prctl cmd = {:x?}", prctl_cmd);
|
debug!("prctl cmd = {:x?}", prctl_cmd);
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
|
@ -8,6 +8,7 @@ pub fn sys_pread64(
|
|||||||
user_buf_ptr: Vaddr,
|
user_buf_ptr: Vaddr,
|
||||||
user_buf_len: usize,
|
user_buf_len: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, buf = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, buf = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
||||||
|
@ -7,7 +7,12 @@ use crate::{
|
|||||||
util::{copy_iovs_from_user, IoVec},
|
util::{copy_iovs_from_user, IoVec},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_readv(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result<SyscallReturn> {
|
pub fn sys_readv(
|
||||||
|
fd: FileDesc,
|
||||||
|
io_vec_ptr: Vaddr,
|
||||||
|
io_vec_count: usize,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_readv(fd, io_vec_ptr, io_vec_count)?;
|
let res = do_sys_readv(fd, io_vec_ptr, io_vec_count)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
@ -17,6 +22,7 @@ pub fn sys_preadv(
|
|||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
let res = do_sys_preadv(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
@ -28,6 +34,7 @@ pub fn sys_preadv2(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = match RWFFlag::from_bits(flags) {
|
let flags = match RWFFlag::from_bits(flags) {
|
||||||
Some(flags) => flags,
|
Some(flags) => flags,
|
||||||
|
@ -11,6 +11,7 @@ pub fn sys_prlimit64(
|
|||||||
resource: u32,
|
resource: u32,
|
||||||
new_rlim_addr: Vaddr,
|
new_rlim_addr: Vaddr,
|
||||||
old_rlim_addr: Vaddr,
|
old_rlim_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let resource = ResourceType::try_from(resource)?;
|
let resource = ResourceType::try_from(resource)?;
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -17,6 +17,7 @@ pub fn sys_pselect6(
|
|||||||
exceptfds_addr: Vaddr,
|
exceptfds_addr: Vaddr,
|
||||||
timespec_addr: Vaddr,
|
timespec_addr: Vaddr,
|
||||||
sigmask_addr: Vaddr,
|
sigmask_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
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();
|
||||||
|
@ -8,6 +8,7 @@ pub fn sys_pwrite64(
|
|||||||
user_buf_ptr: Vaddr,
|
user_buf_ptr: Vaddr,
|
||||||
user_buf_len: usize,
|
user_buf_len: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
||||||
|
@ -3,7 +3,12 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::copy_iovs_from_user};
|
use crate::{fs::file_table::FileDesc, prelude::*, util::copy_iovs_from_user};
|
||||||
|
|
||||||
pub fn sys_writev(fd: FileDesc, io_vec_ptr: Vaddr, io_vec_count: usize) -> Result<SyscallReturn> {
|
pub fn sys_writev(
|
||||||
|
fd: FileDesc,
|
||||||
|
io_vec_ptr: Vaddr,
|
||||||
|
io_vec_count: usize,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_writev(fd, io_vec_ptr, io_vec_count)?;
|
let res = do_sys_writev(fd, io_vec_ptr, io_vec_count)?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
@ -13,6 +18,7 @@ pub fn sys_pwritev(
|
|||||||
io_vec_ptr: Vaddr,
|
io_vec_ptr: Vaddr,
|
||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let res = do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
let res = do_sys_pwritev(fd, io_vec_ptr, io_vec_count, offset, RWFFlag::empty())?;
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
@ -24,6 +30,7 @@ pub fn sys_pwritev2(
|
|||||||
io_vec_count: usize,
|
io_vec_count: usize,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = match RWFFlag::from_bits(flags) {
|
let flags = match RWFFlag::from_bits(flags) {
|
||||||
Some(flags) => flags,
|
Some(flags) => flags,
|
||||||
|
@ -5,7 +5,12 @@ use core::cmp::min;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"fd = {}, user_buf_ptr = 0x{:x}, buf_len = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, buf_len = 0x{:x}",
|
||||||
fd, user_buf_addr, buf_len
|
fd, user_buf_addr, buf_len
|
||||||
|
@ -15,6 +15,7 @@ pub fn sys_readlinkat(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
usr_buf_addr: Vaddr,
|
usr_buf_addr: Vaddr,
|
||||||
usr_buf_len: usize,
|
usr_buf_len: usize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
let path = user_space.read_cstring(path_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -43,6 +44,7 @@ pub fn sys_readlink(
|
|||||||
path_addr: Vaddr,
|
path_addr: Vaddr,
|
||||||
usr_buf_addr: Vaddr,
|
usr_buf_addr: Vaddr,
|
||||||
usr_buf_len: usize,
|
usr_buf_len: usize,
|
||||||
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
self::sys_readlinkat(AT_FDCWD, path_addr, usr_buf_addr, usr_buf_len)
|
self::sys_readlinkat(AT_FDCWD, path_addr, usr_buf_addr, usr_buf_len, ctx)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ pub fn sys_recvfrom(
|
|||||||
flags: i32,
|
flags: i32,
|
||||||
src_addr: Vaddr,
|
src_addr: Vaddr,
|
||||||
addrlen_ptr: Vaddr,
|
addrlen_ptr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = SendRecvFlags::from_bits_truncate(flags);
|
let flags = SendRecvFlags::from_bits_truncate(flags);
|
||||||
debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
|
||||||
|
@ -8,7 +8,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, CUserMsgHdr},
|
util::net::{get_socket_from_fd, CUserMsgHdr},
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(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);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ pub fn sys_renameat(
|
|||||||
old_path_addr: Vaddr,
|
old_path_addr: Vaddr,
|
||||||
new_dirfd: FileDesc,
|
new_dirfd: FileDesc,
|
||||||
new_path_addr: Vaddr,
|
new_path_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let user_space = CurrentUserSpace::get();
|
let user_space = CurrentUserSpace::get();
|
||||||
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
let old_path = user_space.read_cstring(old_path_addr, MAX_FILENAME_LEN)?;
|
||||||
@ -69,6 +70,10 @@ pub fn sys_renameat(
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_rename(old_path_addr: Vaddr, new_path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_rename(
|
||||||
self::sys_renameat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr)
|
old_path_addr: Vaddr,
|
||||||
|
new_path_addr: Vaddr,
|
||||||
|
ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
self::sys_renameat(AT_FDCWD, old_path_addr, AT_FDCWD, new_path_addr, ctx)
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,15 @@ use crate::{
|
|||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rmdir(path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_rmdir(path_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
self::sys_rmdirat(AT_FDCWD, path_addr)
|
self::sys_rmdirat(AT_FDCWD, path_addr, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn sys_rmdirat(dirfd: FileDesc, path_addr: Vaddr) -> Result<SyscallReturn> {
|
pub(super) fn sys_rmdirat(
|
||||||
|
dirfd: FileDesc,
|
||||||
|
path_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let path_addr = CurrentUserSpace::get().read_cstring(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);
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ pub fn sys_rt_sigaction(
|
|||||||
sig_action_addr: Vaddr,
|
sig_action_addr: Vaddr,
|
||||||
old_sig_action_addr: Vaddr,
|
old_sig_action_addr: Vaddr,
|
||||||
sigset_size: u64,
|
sigset_size: u64,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let sig_num = SigNum::try_from(sig_num)?;
|
let sig_num = SigNum::try_from(sig_num)?;
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -5,7 +5,11 @@ use core::sync::atomic::Ordering;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"u_set_ptr = 0x{:x}, sigset_size = {}",
|
"u_set_ptr = 0x{:x}, sigset_size = {}",
|
||||||
u_set_ptr, sigset_size
|
u_set_ptr, sigset_size
|
||||||
|
@ -19,6 +19,7 @@ pub fn sys_rt_sigprocmask(
|
|||||||
set_ptr: Vaddr,
|
set_ptr: Vaddr,
|
||||||
oldset_ptr: Vaddr,
|
oldset_ptr: Vaddr,
|
||||||
sigset_size: usize,
|
sigset_size: usize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let mask_op = MaskOp::try_from(how).unwrap();
|
let mask_op = MaskOp::try_from(how).unwrap();
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -5,14 +5,15 @@ use core::sync::atomic::Ordering;
|
|||||||
use ostd::{cpu::UserContext, user::UserContextApi};
|
use ostd::{cpu::UserContext, user::UserContextApi};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{prelude::*, process::signal::c_types::ucontext_t};
|
||||||
prelude::*,
|
|
||||||
process::{posix_thread::PosixThreadExt, signal::c_types::ucontext_t},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
pub fn sys_rt_sigreturn(ctx: &Context, user_ctx: &mut UserContext) -> Result<SyscallReturn> {
|
||||||
let current_thread = current_thread!();
|
let Context {
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
process: _,
|
||||||
|
posix_thread,
|
||||||
|
thread: _,
|
||||||
|
task: _,
|
||||||
|
} = ctx;
|
||||||
let mut sig_context = posix_thread.sig_context().lock();
|
let mut sig_context = posix_thread.sig_context().lock();
|
||||||
if (*sig_context).is_none() {
|
if (*sig_context).is_none() {
|
||||||
return_errno_with_message!(Errno::EINVAL, "sigreturn should not been called");
|
return_errno_with_message!(Errno::EINVAL, "sigreturn should not been called");
|
||||||
@ -21,13 +22,13 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
|||||||
// FIXME: This assertion is not always true, if RESTORER flag is not presented.
|
// FIXME: This assertion is not always true, if RESTORER flag is not presented.
|
||||||
// In this case, we will put restorer code on user stack, then the assertion will fail.
|
// In this case, we will put restorer code on user stack, then the assertion will fail.
|
||||||
// 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 == user_ctx.stack_pointer() as Vaddr);
|
||||||
|
|
||||||
let ucontext = CurrentUserSpace::get().read_val::<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() {
|
||||||
let rsp = context.stack_pointer();
|
let rsp = user_ctx.stack_pointer();
|
||||||
if rsp >= sig_stack.base() && rsp <= sig_stack.base() + sig_stack.size() {
|
if rsp >= sig_stack.base() && rsp <= sig_stack.base() + sig_stack.size() {
|
||||||
sig_stack.decrease_handler_counter();
|
sig_stack.decrease_handler_counter();
|
||||||
}
|
}
|
||||||
@ -43,7 +44,7 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
|||||||
.uc_mcontext
|
.uc_mcontext
|
||||||
.inner
|
.inner
|
||||||
.gp_regs
|
.gp_regs
|
||||||
.copy_to_raw(context.general_regs_mut());
|
.copy_to_raw(user_ctx.general_regs_mut());
|
||||||
// unblock sig mask
|
// unblock sig mask
|
||||||
let sig_mask = ucontext.uc_sigmask;
|
let sig_mask = ucontext.uc_sigmask;
|
||||||
let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed);
|
let old_mask = posix_thread.sig_mask().load(Ordering::Relaxed);
|
||||||
|
@ -10,7 +10,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result<SyscallReturn> {
|
pub fn sys_rt_sigsuspend(
|
||||||
|
sigmask_addr: Vaddr,
|
||||||
|
sigmask_size: usize,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"sigmask_addr = 0x{:x}, sigmask_size = {}",
|
"sigmask_addr = 0x{:x}, sigmask_size = {}",
|
||||||
sigmask_addr, sigmask_size
|
sigmask_addr, sigmask_size
|
||||||
|
@ -18,6 +18,7 @@ pub fn sys_sched_getaffinity(
|
|||||||
pid: Pid,
|
pid: Pid,
|
||||||
cpuset_size: usize,
|
cpuset_size: usize,
|
||||||
cpu_set_ptr: Vaddr,
|
cpu_set_ptr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let num_cpus = get_num_cpus();
|
let num_cpus = get_num_cpus();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, thread::Thread};
|
use crate::{prelude::*, thread::Thread};
|
||||||
|
|
||||||
pub fn sys_sched_yield() -> Result<SyscallReturn> {
|
pub fn sys_sched_yield(_ctx: &Context) -> Result<SyscallReturn> {
|
||||||
Thread::yield_now();
|
Thread::yield_now();
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ pub fn sys_select(
|
|||||||
writefds_addr: Vaddr,
|
writefds_addr: Vaddr,
|
||||||
exceptfds_addr: Vaddr,
|
exceptfds_addr: Vaddr,
|
||||||
timeval_addr: Vaddr,
|
timeval_addr: Vaddr,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let timeout = if timeval_addr == 0 {
|
let timeout = if timeval_addr == 0 {
|
||||||
None
|
None
|
||||||
|
@ -8,6 +8,7 @@ pub fn sys_sendfile(
|
|||||||
in_fd: FileDesc,
|
in_fd: FileDesc,
|
||||||
offset_ptr: Vaddr,
|
offset_ptr: Vaddr,
|
||||||
count: isize,
|
count: isize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
trace!("raw offset ptr = 0x{:x}", offset_ptr);
|
trace!("raw offset ptr = 0x{:x}", offset_ptr);
|
||||||
|
|
||||||
|
@ -8,7 +8,12 @@ use crate::{
|
|||||||
util::net::{get_socket_from_fd, CUserMsgHdr},
|
util::net::{get_socket_from_fd, CUserMsgHdr},
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
let c_user_msghdr: CUserMsgHdr = CurrentUserSpace::get().read_val(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);
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ pub fn sys_sendto(
|
|||||||
flags: i32,
|
flags: i32,
|
||||||
dest_addr: Vaddr,
|
dest_addr: Vaddr,
|
||||||
addrlen: usize,
|
addrlen: usize,
|
||||||
|
_ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let flags = SendRecvFlags::from_bits_truncate(flags);
|
let flags = SendRecvFlags::from_bits_truncate(flags);
|
||||||
let socket_addr = if dest_addr == 0 {
|
let socket_addr = if dest_addr == 0 {
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
sched::nice::Nice,
|
sched::nice::Nice,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_set_priority(which: i32, who: u32, prio: i32) -> Result<SyscallReturn> {
|
pub fn sys_set_priority(which: i32, who: u32, prio: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let prio_target = PriorityTarget::new(which, who)?;
|
let prio_target = PriorityTarget::new(which, who)?;
|
||||||
let new_nice = {
|
let new_nice = {
|
||||||
let norm_prio = prio.clamp(i8::MIN as i32, i8::MAX as i32) as i8;
|
let norm_prio = prio.clamp(i8::MIN as i32, i8::MAX as i32) as i8;
|
||||||
@ -29,7 +29,7 @@ pub fn sys_set_priority(which: i32, who: u32, prio: i32) -> Result<SyscallReturn
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_get_priority(which: i32, who: u32) -> Result<SyscallReturn> {
|
pub fn sys_get_priority(which: i32, who: u32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let prio_target = PriorityTarget::new(which, who)?;
|
let prio_target = PriorityTarget::new(which, who)?;
|
||||||
debug!("get_priority prio_target: {:?}", prio_target);
|
debug!("get_priority prio_target: {:?}", prio_target);
|
||||||
|
|
||||||
|
@ -6,7 +6,11 @@ use crate::{
|
|||||||
process::posix_thread::{PosixThreadExt, RobustListHead},
|
process::posix_thread::{PosixThreadExt, RobustListHead},
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
|
_ctx: &Context,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!(
|
debug!(
|
||||||
"robust list head ptr: 0x{:x}, len = {}",
|
"robust list head ptr: 0x{:x}, len = {}",
|
||||||
robust_list_head_ptr, len
|
robust_list_head_ptr, len
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
use crate::{prelude::*, process::posix_thread::PosixThreadExt};
|
||||||
|
|
||||||
pub fn sys_set_tid_address(tidptr: Vaddr) -> Result<SyscallReturn> {
|
pub fn sys_set_tid_address(tidptr: Vaddr, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("tidptr = 0x{:x}", tidptr);
|
debug!("tidptr = 0x{:x}", tidptr);
|
||||||
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();
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
process::{credentials_mut, Gid},
|
process::{credentials_mut, Gid},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_setfsgid(gid: i32) -> Result<SyscallReturn> {
|
pub fn sys_setfsgid(gid: i32, _ctx: &Context) -> Result<SyscallReturn> {
|
||||||
debug!("gid = {}", gid);
|
debug!("gid = {}", gid);
|
||||||
|
|
||||||
let fsgid = if gid < 0 {
|
let fsgid = if gid < 0 {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user