mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 19:33:23 +00:00
Fix clippy and compiler warings
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
20a90426a0
commit
9ca64c281e
@ -3,6 +3,7 @@ use crate::fs::fs_resolver::{FsPath, FsResolver};
|
||||
use crate::fs::utils::{Dentry, Inode, InodeMode, InodeType};
|
||||
use crate::prelude::*;
|
||||
|
||||
#[allow(clippy::module_inception)]
|
||||
mod pty;
|
||||
|
||||
pub use pty::{PtyMaster, PtySlave};
|
||||
|
@ -88,7 +88,7 @@ impl PtyMaster {
|
||||
impl FileLike for PtyMaster {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
// TODO: deal with nonblocking read
|
||||
if buf.len() == 0 {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ impl Device for PtySlave {
|
||||
}
|
||||
|
||||
fn id(&self) -> crate::fs::device::DeviceId {
|
||||
DeviceId::new(88, self.index() as u32)
|
||||
DeviceId::new(88, self.index())
|
||||
}
|
||||
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
|
@ -22,7 +22,7 @@ pub struct TtyDriver {
|
||||
}
|
||||
|
||||
impl TtyDriver {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
ttys: SpinLock::new(Vec::new()),
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ pub struct LineDiscipline {
|
||||
pollee: Pollee,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CurrentLine {
|
||||
buffer: StaticRb<u8, BUFFER_CAPACITY>,
|
||||
}
|
||||
@ -66,6 +67,12 @@ impl CurrentLine {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LineDiscipline {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl LineDiscipline {
|
||||
/// Create a new line discipline
|
||||
pub fn new() -> Self {
|
||||
@ -120,7 +127,7 @@ impl LineDiscipline {
|
||||
}
|
||||
}
|
||||
|
||||
if item >= 0x20 && item < 0x7f {
|
||||
if (0x20..0x7f).contains(&item) {
|
||||
// Printable character
|
||||
self.current_line.lock_irq_disabled().push_char(item);
|
||||
}
|
||||
@ -174,7 +181,7 @@ impl LineDiscipline {
|
||||
let backspace: &str = core::str::from_utf8(&[b'\x08', b' ', b'\x08']).unwrap();
|
||||
echo_callback(backspace);
|
||||
}
|
||||
item if 0x20 <= item && item < 0x7f => print!("{}", char::from(item)),
|
||||
item if (0x20..0x7f).contains(&item) => print!("{}", char::from(item)),
|
||||
item if 0 < item && item < 0x20 && termios.contains_echo_ctl() => {
|
||||
// The unprintable chars between 1-31 are mapped to ctrl characters between 65-95.
|
||||
// e.g., 0x3 is mapped to 0x43, which is C. So, we will print ^C when 0x3 is met.
|
||||
@ -263,25 +270,25 @@ impl LineDiscipline {
|
||||
return 0;
|
||||
}
|
||||
let mut read_len = 0;
|
||||
for i in 0..max_read_len {
|
||||
for dst_i in dst.iter_mut().take(max_read_len) {
|
||||
if let Some(next_char) = buffer.pop() {
|
||||
let termios = self.termios.lock_irq_disabled();
|
||||
if termios.is_canonical_mode() {
|
||||
// canonical mode, read until meet new line
|
||||
if meet_new_line(next_char, &termios) {
|
||||
if !should_not_be_read(next_char, &termios) {
|
||||
dst[i] = next_char;
|
||||
*dst_i = next_char;
|
||||
read_len += 1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
dst[i] = next_char;
|
||||
*dst_i = next_char;
|
||||
read_len += 1;
|
||||
}
|
||||
} else {
|
||||
// raw mode
|
||||
// FIXME: avoid addtional bound check
|
||||
dst[i] = next_char;
|
||||
*dst_i = next_char;
|
||||
read_len += 1;
|
||||
}
|
||||
} else {
|
||||
@ -333,7 +340,7 @@ impl LineDiscipline {
|
||||
self.foreground
|
||||
.lock_irq_disabled()
|
||||
.upgrade()
|
||||
.and_then(|foreground| Some(foreground.pgid()))
|
||||
.map(|foreground| foreground.pgid())
|
||||
}
|
||||
|
||||
/// whether there is buffered data
|
||||
@ -359,7 +366,7 @@ impl LineDiscipline {
|
||||
}
|
||||
|
||||
pub fn window_size(&self) -> WinSize {
|
||||
self.winsize.lock().clone()
|
||||
*self.winsize.lock()
|
||||
}
|
||||
|
||||
pub fn set_window_size(&self, winsize: WinSize) {
|
||||
@ -384,9 +391,5 @@ fn meet_new_line(item: u8, termios: &KernelTermios) -> bool {
|
||||
|
||||
/// The special char should not be read by reading process
|
||||
fn should_not_be_read(item: u8, termios: &KernelTermios) -> bool {
|
||||
if item == *termios.get_special_char(CC_C_CHAR::VEOF) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
item == *termios.get_special_char(CC_C_CHAR::VEOF)
|
||||
}
|
||||
|
@ -188,21 +188,21 @@ impl CC_C_CHAR {
|
||||
match self {
|
||||
CC_C_CHAR::VINTR => control_character('C'),
|
||||
CC_C_CHAR::VQUIT => control_character('\\'),
|
||||
CC_C_CHAR::VERASE => '\x7f' as u8,
|
||||
CC_C_CHAR::VERASE => b'\x7f',
|
||||
CC_C_CHAR::VKILL => control_character('U'),
|
||||
CC_C_CHAR::VEOF => control_character('D'),
|
||||
CC_C_CHAR::VTIME => '\0' as u8,
|
||||
CC_C_CHAR::VTIME => b'\0',
|
||||
CC_C_CHAR::VMIN => 1,
|
||||
CC_C_CHAR::VSWTC => '\0' as u8,
|
||||
CC_C_CHAR::VSWTC => b'\0',
|
||||
CC_C_CHAR::VSTART => control_character('Q'),
|
||||
CC_C_CHAR::VSTOP => control_character('S'),
|
||||
CC_C_CHAR::VSUSP => control_character('Z'),
|
||||
CC_C_CHAR::VEOL => '\0' as u8,
|
||||
CC_C_CHAR::VEOL => b'\0',
|
||||
CC_C_CHAR::VREPRINT => control_character('R'),
|
||||
CC_C_CHAR::VDISCARD => control_character('O'),
|
||||
CC_C_CHAR::VWERASE => control_character('W'),
|
||||
CC_C_CHAR::VLNEXT => control_character('V'),
|
||||
CC_C_CHAR::VEOL2 => '\0' as u8,
|
||||
CC_C_CHAR::VEOL2 => b'\0',
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,8 +218,8 @@ pub struct KernelTermios {
|
||||
c_cc: [CcT; KERNEL_NCCS],
|
||||
}
|
||||
|
||||
impl KernelTermios {
|
||||
pub fn default() -> Self {
|
||||
impl Default for KernelTermios {
|
||||
fn default() -> Self {
|
||||
let mut termios = Self {
|
||||
c_iflags: C_IFLAGS::default(),
|
||||
c_oflags: C_OFLAGS::default(),
|
||||
@ -247,7 +247,9 @@ impl KernelTermios {
|
||||
*termios.get_special_char_mut(CC_C_CHAR::VEOL2) = CC_C_CHAR::VEOL2.default_char();
|
||||
termios
|
||||
}
|
||||
}
|
||||
|
||||
impl KernelTermios {
|
||||
pub fn get_special_char(&self, cc_c_char: CC_C_CHAR) -> &CcT {
|
||||
&self.c_cc[cc_c_char as usize]
|
||||
}
|
||||
@ -292,8 +294,8 @@ impl KernelTermios {
|
||||
}
|
||||
|
||||
const fn control_character(c: char) -> u8 {
|
||||
debug_assert!(c as u8 >= 'A' as u8);
|
||||
c as u8 - 'A' as u8 + 1u8
|
||||
debug_assert!(c as u8 >= b'A');
|
||||
c as u8 - b'A' + 1u8
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, Pod)]
|
||||
|
@ -268,13 +268,13 @@ impl From<int_to_c_enum::TryFromIntError> for Error {
|
||||
#[macro_export]
|
||||
macro_rules! return_errno {
|
||||
($errno: expr) => {
|
||||
return core::prelude::v1::Err(crate::error::Error::new($errno))
|
||||
return Err($crate::error::Error::new($errno))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! return_errno_with_message {
|
||||
($errno: expr, $message: expr) => {
|
||||
return core::prelude::v1::Err(crate::error::Error::with_message($errno, $message))
|
||||
return Err($crate::error::Error::with_message($errno, $message))
|
||||
};
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
mod events;
|
||||
mod observer;
|
||||
mod subject;
|
||||
|
@ -14,13 +14,12 @@ pub struct Subject<E: Events, F: EventsFilter<E> = ()> {
|
||||
}
|
||||
|
||||
impl<E: Events, F: EventsFilter<E>> Subject<E, F> {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
observers: Mutex::new(BTreeMap::new()),
|
||||
num_observers: AtomicUsize::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register an observer.
|
||||
///
|
||||
/// A registered observer will get notified through its `on_events` method.
|
||||
|
@ -79,9 +79,9 @@ impl Debug for DeviceId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u64> for DeviceId {
|
||||
fn into(self) -> u64 {
|
||||
self.0
|
||||
impl From<DeviceId> for u64 {
|
||||
fn from(value: DeviceId) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,12 @@ pub struct DevPts {
|
||||
impl DevPts {
|
||||
pub fn new() -> Arc<Self> {
|
||||
let sb = SuperBlock::new(DEVPTS_MAGIC, BLOCK_SIZE, NAME_MAX);
|
||||
let devpts = Arc::new_cyclic(|weak_self| Self {
|
||||
Arc::new_cyclic(|weak_self| Self {
|
||||
root: RootInode::new(weak_self.clone(), &sb),
|
||||
sb,
|
||||
index_alloc: Mutex::new(IdAlloc::with_capacity(MAX_PTY_NUM)),
|
||||
this: weak_self.clone(),
|
||||
});
|
||||
devpts
|
||||
})
|
||||
}
|
||||
|
||||
/// Create the master and slave pair.
|
||||
@ -194,7 +193,7 @@ impl Inode for RootInode {
|
||||
|
||||
// Read the slaves.
|
||||
let slaves = self.slaves.read();
|
||||
let start_offset = offset.clone();
|
||||
let start_offset = *offset;
|
||||
for (idx, (name, node)) in slaves
|
||||
.idxes_and_items()
|
||||
.map(|(idx, (name, node))| (idx + 3, (name, node)))
|
||||
@ -239,7 +238,7 @@ impl Inode for RootInode {
|
||||
.slaves
|
||||
.read()
|
||||
.idxes_and_items()
|
||||
.find(|(_, (child_name, _))| child_name == &slave)
|
||||
.find(|(_, (child_name, _))| child_name == slave)
|
||||
.map(|(_, (_, node))| node.clone())
|
||||
.ok_or(Error::new(Errno::ENOENT))?,
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ pub struct FileTable {
|
||||
}
|
||||
|
||||
impl FileTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
table: SlotVec::new(),
|
||||
subject: Subject::new(),
|
||||
|
@ -23,6 +23,12 @@ impl Clone for FsResolver {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FsResolver {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl FsResolver {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -86,14 +92,13 @@ impl FsResolver {
|
||||
}
|
||||
let (dir_dentry, file_name) =
|
||||
self.lookup_dir_and_base_name_inner(path, follow_tail_link)?;
|
||||
if file_name.ends_with("/") {
|
||||
if file_name.ends_with('/') {
|
||||
return_errno_with_message!(Errno::EISDIR, "path refers to a directory");
|
||||
}
|
||||
if !dir_dentry.vnode().inode_mode().is_writable() {
|
||||
return_errno_with_message!(Errno::EACCES, "file cannot be created");
|
||||
}
|
||||
let new_dentry = dir_dentry.create(&file_name, InodeType::File, inode_mode)?;
|
||||
new_dentry
|
||||
dir_dentry.create(&file_name, InodeType::File, inode_mode)?
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
@ -148,7 +153,7 @@ impl FsResolver {
|
||||
relative_path: &str,
|
||||
follow_tail_link: bool,
|
||||
) -> Result<Arc<Dentry>> {
|
||||
debug_assert!(!relative_path.starts_with("/"));
|
||||
debug_assert!(!relative_path.starts_with('/'));
|
||||
|
||||
if relative_path.len() > PATH_MAX {
|
||||
return_errno_with_message!(Errno::ENAMETOOLONG, "path is too long");
|
||||
@ -195,11 +200,11 @@ impl FsResolver {
|
||||
};
|
||||
|
||||
// Change the dentry and relative path according to symlink
|
||||
if link_path_remain.starts_with("/") {
|
||||
if link_path_remain.starts_with('/') {
|
||||
dentry = self.root.clone();
|
||||
}
|
||||
link_path.clear();
|
||||
link_path.push_str(&link_path_remain.trim_start_matches('/'));
|
||||
link_path.push_str(link_path_remain.trim_start_matches('/'));
|
||||
relative_path = &link_path;
|
||||
follows += 1;
|
||||
} else {
|
||||
@ -269,20 +274,20 @@ impl FsResolver {
|
||||
|
||||
// Dereference the tail symlinks if needed
|
||||
loop {
|
||||
match dir_dentry.lookup(&base_name.trim_end_matches('/')) {
|
||||
match dir_dentry.lookup(base_name.trim_end_matches('/')) {
|
||||
Ok(dentry) if dentry.vnode().inode_type() == InodeType::SymLink => {
|
||||
let link = {
|
||||
let mut link = dentry.vnode().read_link()?;
|
||||
if link.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "invalid symlink");
|
||||
}
|
||||
if base_name.ends_with("/") && !link.ends_with("/") {
|
||||
if base_name.ends_with('/') && !link.ends_with('/') {
|
||||
link += "/";
|
||||
}
|
||||
link
|
||||
};
|
||||
let (dir, file_name) = split_path(&link);
|
||||
if dir.starts_with("/") {
|
||||
if dir.starts_with('/') {
|
||||
dir_dentry =
|
||||
self.lookup_from_parent(&self.root, dir.trim_start_matches('/'), true)?;
|
||||
base_name = String::from(file_name);
|
||||
@ -326,7 +331,7 @@ impl<'a> FsPath<'a> {
|
||||
return_errno_with_message!(Errno::ENAMETOOLONG, "path name too long");
|
||||
}
|
||||
|
||||
let fs_path_inner = if path.starts_with("/") {
|
||||
let fs_path_inner = if path.starts_with('/') {
|
||||
FsPathInner::Absolute(path)
|
||||
} else if dirfd >= 0 {
|
||||
if path.is_empty() {
|
||||
|
@ -53,7 +53,7 @@ impl InodeHandle<Rights> {
|
||||
|
||||
impl Clone for InodeHandle<Rights> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone(), self.1.clone())
|
||||
Self(self.0.clone(), self.1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,7 @@ impl ProcFS {
|
||||
}
|
||||
|
||||
pub(in crate::fs::procfs) fn alloc_id(&self) -> usize {
|
||||
let next_id = self.inode_allocator.fetch_add(1, Ordering::SeqCst);
|
||||
next_id
|
||||
self.inode_allocator.fetch_add(1, Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,7 @@ impl OptionalBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn build(self) -> Result<(Arc<dyn FileSystem>, Option<Weak<dyn Inode>>, bool)> {
|
||||
if self.parent.is_none() && self.fs.is_none() {
|
||||
return_errno_with_message!(Errno::EINVAL, "must have parent or fs");
|
||||
|
@ -124,7 +124,7 @@ impl<D: DirOps + 'static> Inode for ProcDir<D> {
|
||||
// Read the normal child entries.
|
||||
self.inner.populate_children(self.this.clone());
|
||||
let cached_children = self.cached_children.read();
|
||||
let start_offset = offset.clone();
|
||||
let start_offset = *offset;
|
||||
for (idx, (name, child)) in cached_children
|
||||
.idxes_and_items()
|
||||
.map(|(idx, (name, child))| (idx + 2, (name, child)))
|
||||
|
@ -157,6 +157,7 @@ impl Inode_ {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
enum Inner {
|
||||
Dir(DirEntry),
|
||||
File,
|
||||
@ -232,8 +233,7 @@ impl DirEntry {
|
||||
} else {
|
||||
self.children
|
||||
.iter()
|
||||
.find(|(child, _)| child == &Str256::from(name))
|
||||
.is_some()
|
||||
.any(|(child, _)| child == &Str256::from(name))
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ impl DirEntry {
|
||||
*idx += 1;
|
||||
}
|
||||
// Read the normal child entries.
|
||||
let start_idx = idx.clone();
|
||||
let start_idx = *idx;
|
||||
for (offset, (name, child)) in self
|
||||
.children
|
||||
.idxes_and_items()
|
||||
|
@ -15,17 +15,11 @@ pub enum AccessMode {
|
||||
|
||||
impl AccessMode {
|
||||
pub fn is_readable(&self) -> bool {
|
||||
match *self {
|
||||
AccessMode::O_RDONLY | AccessMode::O_RDWR => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, AccessMode::O_RDONLY | AccessMode::O_RDWR)
|
||||
}
|
||||
|
||||
pub fn is_writable(&self) -> bool {
|
||||
match *self {
|
||||
AccessMode::O_WRONLY | AccessMode::O_RDWR => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(*self, AccessMode::O_WRONLY | AccessMode::O_RDWR)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ impl<T: Copy> Producer<T> {
|
||||
return_errno!(Errno::EPIPE);
|
||||
}
|
||||
|
||||
if buf.len() == 0 {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ impl<T: Copy> Consumer<T> {
|
||||
if self.is_shutdown() {
|
||||
return_errno!(Errno::EPIPE);
|
||||
}
|
||||
if buf.len() == 0 {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ impl Dentry {
|
||||
if !self.is_mountpoint() {
|
||||
return self.this();
|
||||
}
|
||||
match self.mount_node().get(&self) {
|
||||
match self.mount_node().get(self) {
|
||||
Some(child_mount) => child_mount.root_dentry().overlaid_dentry(),
|
||||
None => self.this(),
|
||||
}
|
||||
@ -126,7 +126,7 @@ impl Dentry {
|
||||
|
||||
/// Get the DentryKey.
|
||||
pub fn key(&self) -> DentryKey {
|
||||
DentryKey::new(&self)
|
||||
DentryKey::new(self)
|
||||
}
|
||||
|
||||
/// Get the vnode.
|
||||
@ -331,7 +331,7 @@ impl Dentry {
|
||||
Some(dentry) => {
|
||||
children.delete_dentry(old_name);
|
||||
dentry.set_name_and_parent(new_name, self.this());
|
||||
children.insert_dentry(&dentry);
|
||||
children.insert_dentry(dentry);
|
||||
}
|
||||
None => {
|
||||
children.delete_dentry(new_name);
|
||||
@ -343,7 +343,7 @@ impl Dentry {
|
||||
return_errno_with_message!(Errno::EXDEV, "cannot cross mount");
|
||||
}
|
||||
let (mut self_children, mut new_dir_children) =
|
||||
write_lock_children_on_two_dentries(&self, &new_dir);
|
||||
write_lock_children_on_two_dentries(self, new_dir);
|
||||
let old_dentry = self_children.find_dentry_with_checking_mountpoint(old_name)?;
|
||||
let _ = new_dir_children.find_dentry_with_checking_mountpoint(new_name)?;
|
||||
self.vnode.rename(old_name, &new_dir.vnode, new_name)?;
|
||||
@ -351,7 +351,7 @@ impl Dentry {
|
||||
Some(dentry) => {
|
||||
self_children.delete_dentry(old_name);
|
||||
dentry.set_name_and_parent(new_name, new_dir.this());
|
||||
new_dir_children.insert_dentry(&dentry);
|
||||
new_dir_children.insert_dentry(dentry);
|
||||
}
|
||||
None => {
|
||||
new_dir_children.delete_dentry(new_name);
|
||||
@ -473,7 +473,7 @@ impl Dentry {
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert!(path.starts_with("/"));
|
||||
debug_assert!(path.starts_with('/'));
|
||||
path
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,7 @@ pub trait DirEntryVecExt {
|
||||
|
||||
impl DirEntryVecExt for SlotVec<(String, Arc<dyn Inode>)> {
|
||||
fn put_entry_if_not_found(&mut self, name: &str, f: impl Fn() -> Arc<dyn Inode>) {
|
||||
if self
|
||||
.iter()
|
||||
.find(|(child_name, _)| child_name == name)
|
||||
.is_none()
|
||||
{
|
||||
if !self.iter().any(|(child_name, _)| child_name == name) {
|
||||
let inode = f();
|
||||
self.put((String::from(name), inode));
|
||||
}
|
||||
|
@ -23,23 +23,17 @@ pub enum InodeType {
|
||||
|
||||
impl InodeType {
|
||||
pub fn support_read(&self) -> bool {
|
||||
match self {
|
||||
InodeType::File
|
||||
| InodeType::Socket
|
||||
| InodeType::CharDevice
|
||||
| InodeType::BlockDevice => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
self,
|
||||
InodeType::File | InodeType::Socket | InodeType::CharDevice | InodeType::BlockDevice
|
||||
)
|
||||
}
|
||||
|
||||
pub fn support_write(&self) -> bool {
|
||||
match self {
|
||||
InodeType::File
|
||||
| InodeType::Socket
|
||||
| InodeType::CharDevice
|
||||
| InodeType::BlockDevice => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
self,
|
||||
InodeType::File | InodeType::Socket | InodeType::CharDevice | InodeType::BlockDevice
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_reguler_file(&self) -> bool {
|
||||
@ -232,6 +226,10 @@ impl Metadata {
|
||||
pub trait Inode: Any + Sync + Send {
|
||||
fn len(&self) -> usize;
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
fn resize(&self, new_size: usize);
|
||||
|
||||
fn metadata(&self) -> Metadata;
|
||||
|
@ -106,13 +106,11 @@ impl Pager for PageCacheManager {
|
||||
let page_idx = offset / PAGE_SIZE;
|
||||
let mut pages = self.pages.lock();
|
||||
if let Some(page) = pages.pop(&page_idx) {
|
||||
match page.state() {
|
||||
PageState::Dirty => self
|
||||
.backed_inode
|
||||
if let PageState::Dirty = page.state() {
|
||||
self.backed_inode
|
||||
.upgrade()
|
||||
.unwrap()
|
||||
.write_page(page_idx, &page.frame())?,
|
||||
_ => (),
|
||||
.write_page(page_idx, &page.frame())?
|
||||
}
|
||||
} else {
|
||||
warn!("page {} is not in page cache, do nothing", page_idx);
|
||||
|
@ -53,8 +53,7 @@ impl Pollee {
|
||||
self.register_poller(poller.unwrap(), mask);
|
||||
|
||||
// It is important to check events again to handle race conditions
|
||||
let revents = self.events() & mask;
|
||||
revents
|
||||
self.events() & mask
|
||||
}
|
||||
|
||||
fn register_poller(&self, poller: &Poller, mask: IoEvents) {
|
||||
@ -139,6 +138,12 @@ struct PollerInner {
|
||||
pollees: Mutex<BTreeMap<KeyableWeak<PolleeInner>, ()>>,
|
||||
}
|
||||
|
||||
impl Default for Poller {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Poller {
|
||||
/// Constructs a new `Poller`.
|
||||
pub fn new() -> Self {
|
||||
|
@ -235,6 +235,10 @@ impl Vnode {
|
||||
self.inner.read().inode.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
pub fn atime(&self) -> Duration {
|
||||
self.inner.read().inode.atime()
|
||||
}
|
||||
@ -257,7 +261,7 @@ impl Vnode {
|
||||
|
||||
pub fn writer(&self, from_offset: usize) -> VnodeWriter {
|
||||
VnodeWriter {
|
||||
inner: &self,
|
||||
inner: self,
|
||||
offset: from_offset,
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ pub struct AnyUnboundSocket {
|
||||
pollee: Pollee,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub(super) enum AnyRawSocket {
|
||||
Tcp(RawTcpSocket),
|
||||
Udp(RawUdpSocket),
|
||||
|
@ -2,6 +2,7 @@ use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use super::Ipv4Address;
|
||||
use crate::prelude::*;
|
||||
use alloc::collections::btree_map::Entry;
|
||||
use keyable_arc::KeyableWeak;
|
||||
use smoltcp::{
|
||||
iface::{SocketHandle, SocketSet},
|
||||
@ -62,8 +63,8 @@ impl IfaceCommon {
|
||||
fn alloc_ephemeral_port(&self) -> Result<u16> {
|
||||
let mut used_ports = self.used_ports.write();
|
||||
for port in IP_LOCAL_PORT_START..=IP_LOCAL_PORT_END {
|
||||
if !used_ports.contains_key(&port) {
|
||||
used_ports.insert(port, 0);
|
||||
if let Entry::Vacant(e) = used_ports.entry(port) {
|
||||
e.insert(0);
|
||||
return Ok(port);
|
||||
}
|
||||
}
|
||||
@ -74,7 +75,7 @@ impl IfaceCommon {
|
||||
let mut used_ports = self.used_ports.write();
|
||||
if let Some(used_times) = used_ports.get_mut(&port) {
|
||||
if *used_times == 0 || can_reuse {
|
||||
*used_times = *used_times + 1;
|
||||
*used_times += 1;
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EADDRINUSE, "cannot bind port");
|
||||
}
|
||||
@ -163,7 +164,7 @@ impl IfaceCommon {
|
||||
}
|
||||
|
||||
fn insert_bound_socket(&self, socket: &Arc<AnyBoundSocket>) -> Result<()> {
|
||||
let weak_ref = KeyableWeak::from(Arc::downgrade(&socket));
|
||||
let weak_ref = KeyableWeak::from(Arc::downgrade(socket));
|
||||
let mut bound_sockets = self.bound_sockets.write();
|
||||
if bound_sockets.contains(&weak_ref) {
|
||||
return_errno_with_message!(Errno::EINVAL, "the socket is already bound");
|
||||
|
@ -28,7 +28,7 @@ impl IfaceLoopback {
|
||||
let config = Config::new();
|
||||
let mut interface = smoltcp::iface::Interface::new(config, &mut loopback);
|
||||
interface.update_ip_addrs(|ip_addrs| {
|
||||
debug_assert!(ip_addrs.len() == 0);
|
||||
debug_assert!(ip_addrs.is_empty());
|
||||
let ip_addr = IpCidr::new(LOOPBACK_ADDRESS, LOOPBACK_ADDRESS_PREFIX_LEN);
|
||||
ip_addrs.push(ip_addr).unwrap();
|
||||
});
|
||||
|
@ -21,22 +21,16 @@ impl BindPortConfig {
|
||||
} else {
|
||||
Self::Specified(port)
|
||||
}
|
||||
} else if can_reuse {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid bind port config");
|
||||
} else {
|
||||
if can_reuse {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid bind port config");
|
||||
} else {
|
||||
Self::Ephemeral
|
||||
}
|
||||
Self::Ephemeral
|
||||
};
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub(super) fn can_reuse(&self) -> bool {
|
||||
if let Self::CanReuse(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self, Self::CanReuse(_))
|
||||
}
|
||||
|
||||
pub(super) fn port(&self) -> Option<u16> {
|
||||
|
@ -19,7 +19,7 @@ pub struct IfaceVirtio {
|
||||
|
||||
impl IfaceVirtio {
|
||||
pub fn new() -> Arc<Self> {
|
||||
let mut virtio_net = jinux_network::get_device(&(DEVICE_NAME).to_string()).unwrap();
|
||||
let virtio_net = jinux_network::get_device(&(DEVICE_NAME).to_string()).unwrap();
|
||||
let interface = {
|
||||
let mac_addr = virtio_net.lock().mac_addr();
|
||||
let ip_addr = IpCidr::new(wire::IpAddress::Ipv4(wire::Ipv4Address::UNSPECIFIED), 0);
|
||||
@ -33,7 +33,7 @@ impl IfaceVirtio {
|
||||
};
|
||||
let mut interface = smoltcp::iface::Interface::new(config, &mut **virtio_net.lock());
|
||||
interface.update_ip_addrs(|ip_addrs| {
|
||||
debug_assert!(ip_addrs.len() == 0);
|
||||
debug_assert!(ip_addrs.is_empty());
|
||||
ip_addrs.push(ip_addr).unwrap();
|
||||
});
|
||||
interface
|
||||
|
@ -37,11 +37,7 @@ enum Inner {
|
||||
|
||||
impl Inner {
|
||||
fn is_bound(&self) -> bool {
|
||||
if let Inner::Bound { .. } = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self, Inner::Bound { .. })
|
||||
}
|
||||
|
||||
fn bind(&mut self, endpoint: IpEndpoint) -> Result<()> {
|
||||
@ -91,7 +87,7 @@ impl Inner {
|
||||
remote_endpoint, ..
|
||||
} = self
|
||||
{
|
||||
remote_endpoint.clone()
|
||||
*remote_endpoint
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ impl Inner {
|
||||
|
||||
fn bound_socket(&self) -> Option<&Arc<AnyBoundSocket>> {
|
||||
match self {
|
||||
Inner::Bound(bound_socket) => Some(&bound_socket),
|
||||
Inner::Bound(bound_socket) => Some(bound_socket),
|
||||
Inner::Connecting { bound_socket, .. } => Some(bound_socket),
|
||||
_ => None,
|
||||
}
|
||||
@ -96,8 +96,7 @@ impl Inner {
|
||||
|
||||
fn local_endpoint(&self) -> Option<IpEndpoint> {
|
||||
self.bound_socket()
|
||||
.map(|socket| socket.local_endpoint())
|
||||
.flatten()
|
||||
.and_then(|socket| socket.local_endpoint())
|
||||
}
|
||||
|
||||
fn remote_endpoint(&self) -> Option<IpEndpoint> {
|
||||
|
@ -105,7 +105,7 @@ impl ListenStream {
|
||||
backlog_socket.poll(mask, poller);
|
||||
}
|
||||
}
|
||||
return IoEvents::empty();
|
||||
IoEvents::empty()
|
||||
}
|
||||
|
||||
fn bound_socket(&self) -> Arc<AnyBoundSocket> {
|
||||
|
@ -52,7 +52,7 @@ impl Endpoint {
|
||||
}
|
||||
|
||||
pub(super) fn peer_addr(&self) -> Option<UnixSocketAddrBound> {
|
||||
self.0.peer.upgrade().map(|peer| peer.addr()).flatten()
|
||||
self.0.peer.upgrade().and_then(|peer| peer.addr())
|
||||
}
|
||||
|
||||
pub(super) fn is_nonblocking(&self) -> bool {
|
||||
|
@ -205,7 +205,7 @@ fn create_keyable_inode(dentry: &Arc<Dentry>) -> KeyableWeak<dyn Inode> {
|
||||
}
|
||||
|
||||
pub(super) fn unregister_backlog(addr: &UnixSocketAddrBound) {
|
||||
BACKLOG_TABLE.remove_backlog(&addr);
|
||||
BACKLOG_TABLE.remove_backlog(addr);
|
||||
}
|
||||
|
||||
pub(super) fn push_incoming(
|
||||
|
@ -2,6 +2,6 @@ mod connected;
|
||||
mod endpoint;
|
||||
mod init;
|
||||
mod listener;
|
||||
mod stream;
|
||||
mod socket;
|
||||
|
||||
pub use stream::UnixStreamSocket;
|
||||
pub use socket::UnixStreamSocket;
|
||||
|
@ -233,10 +233,8 @@ impl Socket for UnixStreamSocket {
|
||||
};
|
||||
|
||||
match connected.peer_addr() {
|
||||
None => return Ok(SocketAddr::Unix(UnixSocketAddr::Path(String::new()))),
|
||||
Some(peer_addr) => {
|
||||
return Ok(SocketAddr::from(peer_addr.clone()));
|
||||
}
|
||||
None => Ok(SocketAddr::Unix(UnixSocketAddr::Path(String::new()))),
|
||||
Some(peer_addr) => Ok(SocketAddr::from(peer_addr.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,5 +293,5 @@ fn lookup_socket_file(path: &str) -> Result<Arc<Dentry>> {
|
||||
if !dentry.inode_mode().is_readable() || !dentry.inode_mode().is_writable() {
|
||||
return_errno_with_message!(Errno::EACCES, "the socket cannot be read or written")
|
||||
}
|
||||
return Ok(dentry);
|
||||
Ok(dentry)
|
||||
}
|
@ -28,7 +28,7 @@ pub(crate) use pod::Pod;
|
||||
#[macro_export]
|
||||
macro_rules! current {
|
||||
() => {
|
||||
crate::process::Process::current()
|
||||
$crate::process::Process::current()
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ macro_rules! current {
|
||||
#[macro_export]
|
||||
macro_rules! current_thread {
|
||||
() => {
|
||||
crate::thread::Thread::current()
|
||||
$crate::thread::Thread::current()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ fn clone_child_thread(parent_context: UserContext, clone_args: CloneArgs) -> Res
|
||||
// inherit sigmask from current thread
|
||||
let current_thread = current_thread!();
|
||||
let current_posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let sig_mask = current_posix_thread.sig_mask().lock().clone();
|
||||
let sig_mask = *current_posix_thread.sig_mask().lock();
|
||||
let is_main_thread = child_tid == current.pid();
|
||||
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space)
|
||||
.process(Arc::downgrade(¤t))
|
||||
@ -241,7 +241,7 @@ fn clone_child_process(parent_context: UserContext, clone_args: CloneArgs) -> Re
|
||||
// inherit parent's sig mask
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let child_sig_mask = posix_thread.sig_mask().lock().clone();
|
||||
let child_sig_mask = *posix_thread.sig_mask().lock();
|
||||
|
||||
let child_tid = allocate_tid();
|
||||
let mut child_thread_builder = PosixThreadBuilder::new(child_tid, child_user_space)
|
||||
@ -338,7 +338,7 @@ fn clone_cpu_context(
|
||||
tls: u64,
|
||||
clone_flags: CloneFlags,
|
||||
) -> UserContext {
|
||||
let mut child_context = parent_context.clone();
|
||||
let mut child_context = parent_context;
|
||||
// The return value of child thread is zero
|
||||
child_context.set_rax(0);
|
||||
|
||||
@ -390,7 +390,7 @@ fn clone_sighand(
|
||||
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
|
||||
parent_sig_dispositions.clone()
|
||||
} else {
|
||||
Arc::new(Mutex::new(parent_sig_dispositions.lock().clone()))
|
||||
Arc::new(Mutex::new(*parent_sig_dispositions.lock()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,7 @@ impl Process {
|
||||
}
|
||||
|
||||
/// create a new process(not schedule it)
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
pid: Pid,
|
||||
parent: Weak<Process>,
|
||||
@ -328,7 +329,7 @@ impl Process {
|
||||
|
||||
/// returns the root vmar
|
||||
pub fn root_vmar(&self) -> &Vmar<Full> {
|
||||
&self.process_vm.root_vmar()
|
||||
self.process_vm.root_vmar()
|
||||
}
|
||||
|
||||
/// returns the user heap if the process does have, otherwise None
|
||||
|
@ -63,6 +63,7 @@ impl PosixThreadBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn is_main_thread(mut self, is_main_thread: bool) -> Self {
|
||||
self.is_main_thread = is_main_thread;
|
||||
self
|
||||
|
@ -64,7 +64,7 @@ pub fn futex_wake_bitset(
|
||||
) -> Result<usize> {
|
||||
debug!(
|
||||
"futex_wake_bitset addr: {:#x}, max_count: {}, bitset: {:#x}",
|
||||
futex_addr as usize, max_count, bitset
|
||||
futex_addr, max_count, bitset
|
||||
);
|
||||
|
||||
let futex_key = FutexKey::new(futex_addr);
|
||||
@ -234,8 +234,8 @@ impl FutexBucket {
|
||||
if count == max_count {
|
||||
break;
|
||||
}
|
||||
if (*item).key == key {
|
||||
(*item).key = new_key;
|
||||
if item.key == key {
|
||||
item.key = new_key;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,6 @@ impl ThreadName {
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Result<Option<&CStr>> {
|
||||
Ok(Some(&(CStr::from_bytes_until_nul(&self.inner)?)))
|
||||
Ok(Some(CStr::from_bytes_until_nul(&self.inner)?))
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl RobustListHead {
|
||||
///
|
||||
/// The futex refered to by `list_op_pending`, if any, will be returned as
|
||||
/// the last item.
|
||||
pub fn futexes<'a>(&'a self) -> FutexIter<'a> {
|
||||
pub fn futexes(&self) -> FutexIter<'_> {
|
||||
FutexIter::new(self)
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,15 @@ impl ProcessGroup {
|
||||
|
||||
/// send kernel signal to all processes in the group
|
||||
pub fn kernel_signal(&self, signal: KernelSignal) {
|
||||
for (_, process) in &self.inner.lock().processes {
|
||||
process.enqueue_signal(Box::new(signal.clone()));
|
||||
for process in self.inner.lock().processes.values() {
|
||||
process.enqueue_signal(Box::new(signal));
|
||||
}
|
||||
}
|
||||
|
||||
/// send user signal to all processes in the group
|
||||
pub fn user_signal(&self, signal: UserSignal) {
|
||||
for (_, process) in &self.inner.lock().processes {
|
||||
process.enqueue_signal(Box::new(signal.clone()));
|
||||
for process in self.inner.lock().processes.values() {
|
||||
process.enqueue_signal(Box::new(signal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,7 @@ pub fn remove_process(pid: Pid) {
|
||||
|
||||
/// get a process with pid
|
||||
pub fn pid_to_process(pid: Pid) -> Option<Arc<Process>> {
|
||||
PROCESS_TABLE
|
||||
.lock()
|
||||
.get(&pid)
|
||||
.map(|process| process.clone())
|
||||
PROCESS_TABLE.lock().get(&pid).cloned()
|
||||
}
|
||||
|
||||
/// get all processes
|
||||
@ -58,10 +55,7 @@ pub fn remove_process_group(pgid: Pgid) {
|
||||
|
||||
/// get a process group with pgid
|
||||
pub fn pgid_to_process_group(pgid: Pgid) -> Option<Arc<ProcessGroup>> {
|
||||
PROCESS_GROUP_TABLE
|
||||
.lock()
|
||||
.get(&pgid)
|
||||
.map(|process_group| process_group.clone())
|
||||
PROCESS_GROUP_TABLE.lock().get(&pgid).cloned()
|
||||
}
|
||||
|
||||
pub fn register_observer(observer: Weak<dyn Observer<PidEvent>>) {
|
||||
|
@ -10,12 +10,13 @@ use crate::prelude::*;
|
||||
// The map type mask
|
||||
const MAP_TYPE: u32 = 0xf;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, TryFromInt)]
|
||||
#[repr(u8)]
|
||||
pub enum MMapType {
|
||||
MapFile = 0x0,
|
||||
MapShared = 0x1,
|
||||
MapPrivate = 0x2,
|
||||
MapSharedValidate = 0x3,
|
||||
File = 0x0, // Invalid
|
||||
Shared = 0x1,
|
||||
Private = 0x2,
|
||||
SharedValidate = 0x3,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
@ -46,15 +47,10 @@ impl TryFrom<u32> for MMapOptions {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self> {
|
||||
let typ_raw = value & MAP_TYPE;
|
||||
let typ_raw = (value & MAP_TYPE) as u8;
|
||||
let typ = MMapType::try_from(typ_raw)?;
|
||||
|
||||
let flags_raw = value & !MAP_TYPE;
|
||||
let typ = match typ_raw {
|
||||
0x0 => MMapType::MapFile,
|
||||
0x1 => MMapType::MapShared,
|
||||
0x2 => MMapType::MapPrivate,
|
||||
0x3 => MMapType::MapSharedValidate,
|
||||
_ => return Err(Error::with_message(Errno::EINVAL, "unknown mmap flags")),
|
||||
};
|
||||
let Some(flags) = MMapFlags::from_bits(flags_raw) else {
|
||||
return Err(Error::with_message(Errno::EINVAL, "unknown mmap flags"));
|
||||
};
|
||||
|
@ -40,16 +40,14 @@ impl UserHeap {
|
||||
.offset(self.heap_base)
|
||||
.size(self.heap_size_limit);
|
||||
vmar_map_options.build().unwrap();
|
||||
return self.current_heap_end.load(Ordering::Relaxed);
|
||||
self.current_heap_end.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn brk(&self, new_heap_end: Option<Vaddr>) -> Result<Vaddr> {
|
||||
let current = current!();
|
||||
let root_vmar = current.root_vmar();
|
||||
match new_heap_end {
|
||||
None => {
|
||||
return Ok(self.current_heap_end.load(Ordering::Relaxed));
|
||||
}
|
||||
None => Ok(self.current_heap_end.load(Ordering::Relaxed)),
|
||||
Some(new_heap_end) => {
|
||||
if new_heap_end > self.heap_base + self.heap_size_limit {
|
||||
return_errno_with_message!(Errno::ENOMEM, "heap size limit was met.");
|
||||
@ -64,7 +62,7 @@ impl UserHeap {
|
||||
let heap_vmo = heap_mapping.vmo();
|
||||
heap_vmo.resize(new_size)?;
|
||||
self.current_heap_end.store(new_heap_end, Ordering::Release);
|
||||
return Ok(new_heap_end);
|
||||
Ok(new_heap_end)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,8 +80,8 @@ impl Clone for UserHeap {
|
||||
fn clone(&self) -> Self {
|
||||
let current_heap_end = self.current_heap_end.load(Ordering::Relaxed);
|
||||
Self {
|
||||
heap_base: self.heap_base.clone(),
|
||||
heap_size_limit: self.heap_size_limit.clone(),
|
||||
heap_base: self.heap_base,
|
||||
heap_size_limit: self.heap_size_limit,
|
||||
current_heap_end: AtomicUsize::new(current_heap_end),
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ impl AuxVec {
|
||||
}
|
||||
|
||||
pub fn get(&self, key: AuxKey) -> Option<u64> {
|
||||
self.table.get(&key).map(|val_ref| *val_ref)
|
||||
self.table.get(&key).copied()
|
||||
}
|
||||
|
||||
pub fn del(&mut self, key: AuxKey) -> Option<u64> {
|
||||
|
@ -33,7 +33,7 @@ impl Elf {
|
||||
let program_header = xmas_elf::program::parse_program_header(input, header, index)
|
||||
.map_err(|_| Error::with_message(Errno::ENOEXEC, "parse program header fails"))?;
|
||||
let ph64 = match program_header {
|
||||
xmas_elf::program::ProgramHeader::Ph64(ph64) => ph64.clone(),
|
||||
xmas_elf::program::ProgramHeader::Ph64(ph64) => *ph64,
|
||||
xmas_elf::program::ProgramHeader::Ph32(_) => {
|
||||
return_errno_with_message!(Errno::ENOEXEC, "Not 64 byte executable")
|
||||
}
|
||||
@ -111,7 +111,7 @@ impl Elf {
|
||||
|
||||
// An offset to be subtracted from ELF vaddr for PIE
|
||||
pub fn base_load_address_offset(&self) -> u64 {
|
||||
let phdr = self.program_headers.iter().nth(0).unwrap();
|
||||
let phdr = self.program_headers.get(0).unwrap();
|
||||
phdr.virtual_addr - phdr.offset
|
||||
}
|
||||
}
|
||||
@ -123,7 +123,7 @@ pub struct ElfHeader {
|
||||
|
||||
impl ElfHeader {
|
||||
fn parse_elf_header(header: Header) -> Result<Self> {
|
||||
let pt1 = header.pt1.clone();
|
||||
let pt1 = *header.pt1;
|
||||
let pt2 = match header.pt2 {
|
||||
HeaderPt2::Header64(header_pt2) => {
|
||||
let HeaderPt2_ {
|
||||
|
@ -184,7 +184,7 @@ impl InitStack {
|
||||
let ldso_base = ldso_load_info.base_addr();
|
||||
aux_vec.set(AuxKey::AT_BASE, ldso_base as u64)?;
|
||||
}
|
||||
self.adjust_stack_alignment(root_vmar, &envp_pointers, &argv_pointers, &aux_vec)?;
|
||||
self.adjust_stack_alignment(root_vmar, &envp_pointers, &argv_pointers, aux_vec)?;
|
||||
self.write_aux_vec(root_vmar, aux_vec)?;
|
||||
self.write_envp_pointers(root_vmar, envp_pointers)?;
|
||||
self.write_argv_pointers(root_vmar, argv_pointers)?;
|
||||
@ -195,11 +195,7 @@ impl InitStack {
|
||||
}
|
||||
|
||||
fn write_envp_strings(&mut self, root_vmar: &Vmar<Full>) -> Result<Vec<u64>> {
|
||||
let envp = self
|
||||
.envp
|
||||
.iter()
|
||||
.map(|envp| envp.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let envp = self.envp.to_vec();
|
||||
let mut envp_pointers = Vec::with_capacity(envp.len());
|
||||
for envp in envp.iter() {
|
||||
let pointer = self.write_cstring(envp, root_vmar)?;
|
||||
@ -209,11 +205,7 @@ impl InitStack {
|
||||
}
|
||||
|
||||
fn write_argv_strings(&mut self, root_vmar: &Vmar<Full>) -> Result<Vec<u64>> {
|
||||
let argv = self
|
||||
.argv
|
||||
.iter()
|
||||
.map(|argv| argv.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let argv = self.argv.to_vec();
|
||||
let mut argv_pointers = Vec::with_capacity(argv.len());
|
||||
for argv in argv.iter().rev() {
|
||||
let pointer = self.write_cstring(argv, root_vmar)?;
|
||||
@ -224,7 +216,7 @@ impl InitStack {
|
||||
Ok(argv_pointers)
|
||||
}
|
||||
|
||||
fn write_aux_vec(&mut self, root_vmar: &Vmar<Full>, aux_vec: &mut AuxVec) -> Result<()> {
|
||||
fn write_aux_vec(&mut self, root_vmar: &Vmar<Full>, aux_vec: &AuxVec) -> Result<()> {
|
||||
// Write NULL auxilary
|
||||
self.write_u64(0, root_vmar)?;
|
||||
self.write_u64(AuxKey::AT_NULL as u64, root_vmar)?;
|
||||
|
@ -43,7 +43,7 @@ pub fn load_elf_to_vm(
|
||||
process_vm.clear();
|
||||
|
||||
match init_and_map_vmos(process_vm, ldso, &elf, &elf_file, argv, envp) {
|
||||
Ok(elf_load_info) => return Ok(elf_load_info),
|
||||
Ok(elf_load_info) => Ok(elf_load_info),
|
||||
Err(e) => {
|
||||
// Since the process_vm is cleared, the process cannot return to user space again,
|
||||
// so exit_group is called here.
|
||||
@ -78,7 +78,7 @@ fn lookup_and_parse_ldso(
|
||||
}
|
||||
|
||||
fn load_ldso(root_vmar: &Vmar<Full>, ldso_file: &Dentry, ldso_elf: &Elf) -> Result<LdsoLoadInfo> {
|
||||
let map_addr = map_segment_vmos(&ldso_elf, root_vmar, &ldso_file)?;
|
||||
let map_addr = map_segment_vmos(ldso_elf, root_vmar, ldso_file)?;
|
||||
Ok(LdsoLoadInfo::new(
|
||||
ldso_elf.entry_point() + map_addr,
|
||||
map_addr,
|
||||
@ -102,21 +102,19 @@ fn init_and_map_vmos(
|
||||
None
|
||||
};
|
||||
|
||||
let map_addr = map_segment_vmos(&elf, root_vmar, &elf_file)?;
|
||||
let mut aux_vec = init_aux_vec(&elf, map_addr)?;
|
||||
let map_addr = map_segment_vmos(elf, root_vmar, elf_file)?;
|
||||
let mut aux_vec = init_aux_vec(elf, map_addr)?;
|
||||
let mut init_stack = InitStack::new_default_config(argv, envp);
|
||||
init_stack.init(root_vmar, &elf, &ldso_load_info, &mut aux_vec)?;
|
||||
init_stack.init(root_vmar, elf, &ldso_load_info, &mut aux_vec)?;
|
||||
let entry_point = if let Some(ldso_load_info) = ldso_load_info {
|
||||
// Normal shared object
|
||||
ldso_load_info.entry_point()
|
||||
} else if elf.is_shared_object() {
|
||||
// ldso itself
|
||||
elf.entry_point() + map_addr
|
||||
} else {
|
||||
if elf.is_shared_object() {
|
||||
// ldso itself
|
||||
elf.entry_point() + map_addr
|
||||
} else {
|
||||
// statically linked executable
|
||||
elf.entry_point()
|
||||
}
|
||||
// statically linked executable
|
||||
elf.entry_point()
|
||||
};
|
||||
|
||||
let elf_load_info = ElfLoadInfo::new(entry_point, init_stack.user_stack_top());
|
||||
|
@ -32,16 +32,14 @@ pub fn handle_pending_signal(context: &mut UserContext) -> Result<()> {
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let pid = current.pid();
|
||||
let sig_mask = posix_thread.sig_mask().lock().clone();
|
||||
let sig_mask = *posix_thread.sig_mask().lock();
|
||||
let mut thread_sig_queues = posix_thread.sig_queues().lock();
|
||||
let mut proc_sig_queues = current.sig_queues().lock();
|
||||
// We first deal with signal in current thread, then signal in current process.
|
||||
let signal = if let Some(signal) = thread_sig_queues.dequeue(&sig_mask) {
|
||||
Some(signal)
|
||||
} else if let Some(signal) = proc_sig_queues.dequeue(&sig_mask) {
|
||||
Some(signal)
|
||||
} else {
|
||||
None
|
||||
proc_sig_queues.dequeue(&sig_mask)
|
||||
};
|
||||
if let Some(signal) = signal {
|
||||
let sig_num = signal.num();
|
||||
@ -132,18 +130,20 @@ pub fn handle_user_signal(
|
||||
// Set up signal stack in user stack,
|
||||
// to avoid corrupting user stack, we minus 128 first.
|
||||
let mut user_rsp = context.rsp() as u64;
|
||||
user_rsp = user_rsp - 128;
|
||||
user_rsp -= 128;
|
||||
|
||||
// 1. write siginfo_t
|
||||
user_rsp = user_rsp - mem::size_of::<siginfo_t>() as u64;
|
||||
user_rsp -= mem::size_of::<siginfo_t>() as u64;
|
||||
write_val_to_user(user_rsp as _, &sig_info)?;
|
||||
let siginfo_addr = user_rsp;
|
||||
// debug!("siginfo_addr = 0x{:x}", siginfo_addr);
|
||||
|
||||
// 2. write ucontext_t.
|
||||
user_rsp = alloc_aligned_in_user_stack(user_rsp, mem::size_of::<ucontext_t>(), 16)?;
|
||||
let mut ucontext = ucontext_t::default();
|
||||
ucontext.uc_sigmask = mask.as_u64();
|
||||
let mut ucontext = ucontext_t {
|
||||
uc_sigmask: mask.as_u64(),
|
||||
..Default::default()
|
||||
};
|
||||
ucontext.uc_mcontext.inner.gp_regs = *context.general_regs();
|
||||
let mut sig_context = posix_thread.sig_context().lock();
|
||||
if let Some(sig_context_addr) = *sig_context {
|
||||
@ -172,7 +172,7 @@ pub fn handle_user_signal(
|
||||
0x0f, 0x05, // syscall (call rt_sigreturn)
|
||||
0x90, // nop (for alignment)
|
||||
];
|
||||
user_rsp = user_rsp - TRAMPOLINE.len() as u64;
|
||||
user_rsp -= TRAMPOLINE.len() as u64;
|
||||
let trampoline_rip = user_rsp;
|
||||
write_bytes_to_user(user_rsp as Vaddr, TRAMPOLINE)?;
|
||||
user_rsp = write_u64_to_user_stack(user_rsp, trampoline_rip)?;
|
||||
|
@ -2,8 +2,9 @@ use super::{c_types::sigaction_t, constants::*, sig_mask::SigMask, sig_num::SigN
|
||||
use crate::prelude::*;
|
||||
use bitflags::bitflags;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
|
||||
pub enum SigAction {
|
||||
#[default]
|
||||
Dfl, // Default action
|
||||
Ign, // Ignore this signal
|
||||
User {
|
||||
@ -15,12 +16,6 @@ pub enum SigAction {
|
||||
},
|
||||
}
|
||||
|
||||
impl Default for SigAction {
|
||||
fn default() -> Self {
|
||||
SigAction::Dfl
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<sigaction_t> for SigAction {
|
||||
type Error = Error;
|
||||
|
||||
@ -44,7 +39,7 @@ impl TryFrom<sigaction_t> for SigAction {
|
||||
}
|
||||
|
||||
impl SigAction {
|
||||
pub fn to_c(&self) -> sigaction_t {
|
||||
pub fn as_c_type(&self) -> sigaction_t {
|
||||
match self {
|
||||
SigAction::Dfl => sigaction_t {
|
||||
handler_ptr: SIG_DFL,
|
||||
@ -65,7 +60,7 @@ impl SigAction {
|
||||
mask,
|
||||
} => sigaction_t {
|
||||
handler_ptr: *handler_addr,
|
||||
flags: flags.to_u32(),
|
||||
flags: flags.as_u32(),
|
||||
restorer_ptr: *restorer_addr,
|
||||
mask: mask.as_u64(),
|
||||
},
|
||||
@ -100,7 +95,7 @@ impl TryFrom<u32> for SigActionFlags {
|
||||
}
|
||||
|
||||
impl SigActionFlags {
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
pub fn as_u32(&self) -> u32 {
|
||||
self.bits()
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,12 @@ pub struct SigDispositions {
|
||||
map: [SigAction; COUNT_ALL_SIGS],
|
||||
}
|
||||
|
||||
impl Default for SigDispositions {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl SigDispositions {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -34,11 +40,8 @@ impl SigDispositions {
|
||||
/// This function should be used when execve.
|
||||
pub fn inherit(&mut self) {
|
||||
for sigaction in &mut self.map {
|
||||
match sigaction {
|
||||
SigAction::User { .. } => {
|
||||
*sigaction = SigAction::Dfl;
|
||||
}
|
||||
_ => {}
|
||||
if let SigAction::User { .. } = sigaction {
|
||||
*sigaction = SigAction::Dfl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ impl TryFrom<u8> for SigNum {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(sig_num: u8) -> Result<Self> {
|
||||
if sig_num > MAX_RT_SIG_NUM || sig_num < MIN_STD_SIG_NUM {
|
||||
if !(MIN_STD_SIG_NUM..=MAX_RT_SIG_NUM).contains(&sig_num) {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid signal number");
|
||||
}
|
||||
Ok(SigNum { sig_num })
|
||||
|
@ -19,7 +19,6 @@ impl Signal for KernelSignal {
|
||||
}
|
||||
|
||||
fn to_info(&self) -> siginfo_t {
|
||||
let info = siginfo_t::new(self.num, SI_KERNEL);
|
||||
info
|
||||
siginfo_t::new(self.num, SI_KERNEL)
|
||||
}
|
||||
}
|
||||
|
@ -61,13 +61,11 @@ impl Signal for UserSignal {
|
||||
UserSignalKind::Sigqueue => SI_QUEUE,
|
||||
};
|
||||
|
||||
let info = siginfo_t::new(self.num, code);
|
||||
siginfo_t::new(self.num, code)
|
||||
// info.set_si_pid(self.pid);
|
||||
// info.set_si_uid(self.uid);
|
||||
// if let UserSignalKind::Sigqueue(val) = self.kind {
|
||||
// info.set_si_value(val);
|
||||
// }
|
||||
|
||||
info
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub fn wait_child_exit(
|
||||
// we need to drop the lock here, since reap child process need to acquire this lock again
|
||||
drop(children_lock);
|
||||
|
||||
if unwaited_children.len() == 0 {
|
||||
if unwaited_children.is_empty() {
|
||||
return Some(Err(jinux_frame::Error::NoChild));
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ struct c_epoll_event {
|
||||
impl From<&EpollEvent> for c_epoll_event {
|
||||
fn from(ep_event: &EpollEvent) -> Self {
|
||||
Self {
|
||||
events: ep_event.events.bits() as u32,
|
||||
events: ep_event.events.bits(),
|
||||
data: ep_event.user_data,
|
||||
}
|
||||
}
|
||||
@ -150,9 +150,6 @@ impl From<&EpollEvent> for c_epoll_event {
|
||||
|
||||
impl From<&c_epoll_event> for EpollEvent {
|
||||
fn from(c_event: &c_epoll_event) -> Self {
|
||||
Self::new(
|
||||
IoEvents::from_bits_truncate(c_event.events as u32),
|
||||
c_event.data,
|
||||
)
|
||||
Self::new(IoEvents::from_bits_truncate(c_event.events), c_event.data)
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ fn lookup_executable_file(
|
||||
) -> Result<Arc<Dentry>> {
|
||||
let current = current!();
|
||||
let fs_resolver = current.fs().read();
|
||||
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.len() == 0 {
|
||||
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
|
||||
fs_resolver.lookup_from_fd(dfd)
|
||||
} else {
|
||||
let fs_path = FsPath::new(dfd, &filename)?;
|
||||
|
@ -15,14 +15,14 @@ pub fn sys_fcntl(fd: FileDescripter, cmd: i32, arg: u64) -> Result<SyscallReturn
|
||||
let current = current!();
|
||||
let mut file_table = current.file_table().lock();
|
||||
let new_fd = file_table.dup(fd, arg as FileDescripter)?;
|
||||
return Ok(SyscallReturn::Return(new_fd as _));
|
||||
Ok(SyscallReturn::Return(new_fd as _))
|
||||
}
|
||||
FcntlCmd::F_SETFD => {
|
||||
if arg != 1 {
|
||||
panic!("Unknown setfd argument");
|
||||
}
|
||||
// TODO: Set cloexec
|
||||
return Ok(SyscallReturn::Return(0));
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
FcntlCmd::F_GETFL => {
|
||||
let current = current!();
|
||||
@ -32,9 +32,9 @@ pub fn sys_fcntl(fd: FileDescripter, cmd: i32, arg: u64) -> Result<SyscallReturn
|
||||
};
|
||||
let status_flags = file.status_flags();
|
||||
let access_mode = file.access_mode();
|
||||
return Ok(SyscallReturn::Return(
|
||||
Ok(SyscallReturn::Return(
|
||||
(status_flags.bits() | access_mode as u32) as _,
|
||||
));
|
||||
))
|
||||
}
|
||||
FcntlCmd::F_SETFL => {
|
||||
let current = current!();
|
||||
@ -56,7 +56,7 @@ pub fn sys_fcntl(fd: FileDescripter, cmd: i32, arg: u64) -> Result<SyscallReturn
|
||||
status_flags
|
||||
};
|
||||
file.set_status_flags(new_status_flags)?;
|
||||
return Ok(SyscallReturn::Return(0));
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ pub fn sys_ioctl(fd: FileDescripter, cmd: u32, arg: Vaddr) -> Result<SyscallRetu
|
||||
let file_table = current.file_table().lock();
|
||||
let file = file_table.get_file(fd)?;
|
||||
let res = file.ioctl(ioctl_cmd, arg)?;
|
||||
return Ok(SyscallReturn::Return(res as _));
|
||||
Ok(SyscallReturn::Return(res as _))
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ pub fn do_sys_kill(filter: ProcessFilter, sig_num: SigNum) -> Result<()> {
|
||||
match filter {
|
||||
ProcessFilter::Any => {
|
||||
for process in process_table::get_all_processes() {
|
||||
process.enqueue_signal(Box::new(signal.clone()));
|
||||
process.enqueue_signal(Box::new(signal));
|
||||
}
|
||||
}
|
||||
ProcessFilter::WithPid(pid) => {
|
||||
|
@ -30,14 +30,14 @@ pub fn sys_linkat(
|
||||
let current = current!();
|
||||
let (old_dentry, new_dir_dentry, new_name) = {
|
||||
let old_pathname = old_pathname.to_string_lossy();
|
||||
if old_pathname.ends_with("/") {
|
||||
if old_pathname.ends_with('/') {
|
||||
return_errno_with_message!(Errno::EPERM, "oldpath is dir");
|
||||
}
|
||||
if old_pathname.is_empty() && !flags.contains(LinkFlags::AT_EMPTY_PATH) {
|
||||
return_errno_with_message!(Errno::ENOENT, "oldpath is empty");
|
||||
}
|
||||
let new_pathname = new_pathname.to_string_lossy();
|
||||
if new_pathname.ends_with("/") {
|
||||
if new_pathname.ends_with('/') {
|
||||
return_errno_with_message!(Errno::EPERM, "newpath is dir");
|
||||
}
|
||||
if new_pathname.is_empty() {
|
||||
|
@ -33,7 +33,7 @@ pub fn sys_mkdirat(
|
||||
current.fs().read().lookup_dir_and_base_name(&fs_path)?
|
||||
};
|
||||
let inode_mode = InodeMode::from_bits_truncate(mode);
|
||||
let _ = dir_dentry.create(&name.trim_end_matches('/'), InodeType::Dir, inode_mode)?;
|
||||
let _ = dir_dentry.create(name.trim_end_matches('/'), InodeType::Dir, inode_mode)?;
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ fn mmap_anonymous_vmo(
|
||||
debug_assert!(offset == 0);
|
||||
|
||||
// TODO: implement features presented by other flags.
|
||||
if option.typ() != MMapType::MapPrivate {
|
||||
if option.typ() != MMapType::Private {
|
||||
panic!("Unsupported mmap flags {:?} now", option);
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ fn mmap_filebacked_vmo(
|
||||
))?
|
||||
};
|
||||
|
||||
let vmo = if option.typ() == MMapType::MapPrivate {
|
||||
let vmo = if option.typ() == MMapType::Private {
|
||||
// map private
|
||||
VmoChildOptions::new_cow(page_cache_vmo, offset..(offset + len)).alloc()?
|
||||
} else {
|
||||
|
@ -406,8 +406,8 @@ pub fn syscall_dispatch(
|
||||
SYS_SOCKETPAIR => syscall_handler!(4, sys_socketpair, args),
|
||||
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
|
||||
SYS_GETSOCKOPT => syscall_handler!(5, sys_getsockopt, args),
|
||||
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
|
||||
SYS_FORK => syscall_handler!(0, sys_fork, context.clone()),
|
||||
SYS_CLONE => syscall_handler!(5, sys_clone, args, *context),
|
||||
SYS_FORK => syscall_handler!(0, sys_fork, *context),
|
||||
SYS_EXECVE => syscall_handler!(3, sys_execve, args, context),
|
||||
SYS_EXIT => syscall_handler!(1, sys_exit, args),
|
||||
SYS_WAIT4 => syscall_handler!(3, sys_wait4, args),
|
||||
|
@ -154,11 +154,7 @@ impl From<c_pollfd> for PollFd {
|
||||
|
||||
impl From<PollFd> for c_pollfd {
|
||||
fn from(raw: PollFd) -> Self {
|
||||
let fd = if let Some(fd) = raw.fd() {
|
||||
fd as i32
|
||||
} else {
|
||||
-1
|
||||
};
|
||||
let fd = if let Some(fd) = raw.fd() { fd } else { -1 };
|
||||
let events = raw.events().bits() as i16;
|
||||
let revents = raw.revents().get().bits() as i16;
|
||||
Self {
|
||||
|
@ -17,5 +17,5 @@ pub fn sys_read(fd: FileDescripter, user_buf_addr: Vaddr, buf_len: usize) -> Res
|
||||
let mut read_buf = vec![0u8; buf_len];
|
||||
let read_len = file.read(&mut read_buf)?;
|
||||
write_bytes_to_user(user_buf_addr, &read_buf)?;
|
||||
return Ok(SyscallReturn::Return(read_len as _));
|
||||
Ok(SyscallReturn::Return(read_len as _))
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ pub fn sys_renameat(
|
||||
if new_pathname.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "newpath is empty");
|
||||
}
|
||||
if new_pathname.ends_with("/") && old_dentry.inode_type() != InodeType::Dir {
|
||||
if new_pathname.ends_with('/') && old_dentry.inode_type() != InodeType::Dir {
|
||||
return_errno_with_message!(Errno::ENOTDIR, "oldpath is not dir");
|
||||
}
|
||||
let new_fs_path = FsPath::new(new_dirfd, new_pathname.as_ref().trim_end_matches('/'))?;
|
||||
|
@ -18,6 +18,6 @@ pub fn sys_rmdir(pathname_addr: Vaddr) -> Result<SyscallReturn> {
|
||||
let fs_path = FsPath::try_from(pathname.as_ref())?;
|
||||
current.fs().read().lookup_dir_and_base_name(&fs_path)?
|
||||
};
|
||||
dir_dentry.rmdir(&name.trim_end_matches('/'))?;
|
||||
dir_dentry.rmdir(name.trim_end_matches('/'))?;
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub fn sys_rt_sigaction(
|
||||
let current = current!();
|
||||
let mut sig_dispositions = current.sig_dispositions().lock();
|
||||
let old_action = sig_dispositions.get(sig_num);
|
||||
let old_action_c = old_action.to_c();
|
||||
let old_action_c = old_action.as_c_type();
|
||||
if old_sig_action_addr != 0 {
|
||||
write_val_to_user(old_sig_action_addr, &old_action_c)?;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ pub fn sys_rt_sigreturn(context: &mut UserContext) -> Result<SyscallReturn> {
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let mut sig_context = posix_thread.sig_context().lock();
|
||||
if None == *sig_context {
|
||||
if (*sig_context).is_none() {
|
||||
return_errno_with_message!(Errno::EINVAL, "sigretrun should not been called");
|
||||
}
|
||||
let sig_context_addr = sig_context.unwrap();
|
||||
|
@ -100,9 +100,15 @@ fn do_select(
|
||||
};
|
||||
|
||||
// Clear up the three input fd_set's, which will be used for output as well
|
||||
readfds.as_mut().map_or((), |fds| fds.clear());
|
||||
writefds.as_mut().map_or((), |fds| fds.clear());
|
||||
exceptfds.as_mut().map_or((), |fds| fds.clear());
|
||||
if let Some(fds) = readfds.as_mut() {
|
||||
fds.clear();
|
||||
}
|
||||
if let Some(fds) = writefds.as_mut() {
|
||||
fds.clear();
|
||||
}
|
||||
if let Some(fds) = exceptfds.as_mut() {
|
||||
fds.clear();
|
||||
}
|
||||
|
||||
// Do the poll syscall that is equivalent to the select syscall
|
||||
let num_revents = do_poll(&poll_fds, timeout)?;
|
||||
|
@ -34,7 +34,7 @@ pub fn sys_symlinkat(
|
||||
if linkpath.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "linkpath is empty");
|
||||
}
|
||||
if linkpath.ends_with("/") {
|
||||
if linkpath.ends_with('/') {
|
||||
return_errno_with_message!(Errno::EISDIR, "linkpath is dir");
|
||||
}
|
||||
let fs_path = FsPath::new(dirfd, linkpath.as_ref())?;
|
||||
|
@ -31,7 +31,7 @@ pub fn sys_unlinkat(
|
||||
if pathname.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||
}
|
||||
if pathname.ends_with("/") {
|
||||
if pathname.ends_with('/') {
|
||||
return_errno_with_message!(Errno::EISDIR, "unlink on directory");
|
||||
}
|
||||
let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
|
||||
|
@ -24,7 +24,7 @@ pub fn sys_write(
|
||||
let file_table = current.file_table().lock();
|
||||
let file = file_table.get_file(fd)?;
|
||||
let mut buffer = vec![0u8; user_buf_len];
|
||||
read_bytes_from_user(user_buf_ptr as usize, &mut buffer)?;
|
||||
read_bytes_from_user(user_buf_ptr, &mut buffer)?;
|
||||
debug!("write content = {:?}", buffer);
|
||||
let write_len = file.write(&buffer)?;
|
||||
Ok(SyscallReturn::Return(write_len as _))
|
||||
|
@ -4,7 +4,7 @@ use crate::vm::page_fault_handler::PageFaultHandler;
|
||||
use crate::{prelude::*, process::signal::signals::fault::FaultSignal};
|
||||
|
||||
/// We can't handle most exceptions, just send self a fault signal before return to user space.
|
||||
pub fn handle_exception(context: &mut UserContext) {
|
||||
pub fn handle_exception(context: &UserContext) {
|
||||
let trap_info = context.trap_information();
|
||||
let exception = CpuException::to_cpu_exception(trap_info.id as u16).unwrap();
|
||||
log_trap_info(exception, trap_info);
|
||||
@ -12,10 +12,10 @@ pub fn handle_exception(context: &mut UserContext) {
|
||||
let root_vmar = current.root_vmar();
|
||||
|
||||
match *exception {
|
||||
PAGE_FAULT => handle_page_fault(&trap_info),
|
||||
PAGE_FAULT => handle_page_fault(trap_info),
|
||||
_ => {
|
||||
// We current do nothing about other exceptions
|
||||
generate_fault_signal(&trap_info);
|
||||
generate_fault_signal(trap_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ impl Thread {
|
||||
self.tid
|
||||
}
|
||||
|
||||
// The return type must be borrowed box, otherwise the downcast_ref will fail
|
||||
#[allow(clippy::borrowed_box)]
|
||||
pub fn data(&self) -> &Box<dyn Send + Sync + Any> {
|
||||
&self.data
|
||||
}
|
||||
|
@ -16,5 +16,5 @@ pub fn remove_thread(tid: Tid) {
|
||||
}
|
||||
|
||||
pub fn tid_to_thread(tid: Tid) -> Option<Arc<Thread>> {
|
||||
THREAD_TABLE.lock().get(&tid).map(|thread| thread.clone())
|
||||
THREAD_TABLE.lock().get(&tid).cloned()
|
||||
}
|
||||
|
@ -33,13 +33,13 @@ impl SystemTime {
|
||||
/// Add a duration to self. If the result does not exceed inner bounds return Some(t), else return None.
|
||||
pub fn checked_add(&self, duration: Duration) -> Option<Self> {
|
||||
let duration = convert_to_time_duration(duration);
|
||||
self.0.checked_add(duration).map(|inner| SystemTime(inner))
|
||||
self.0.checked_add(duration).map(SystemTime)
|
||||
}
|
||||
|
||||
/// Substract a duration from self. If the result does not exceed inner bounds return Some(t), else return None.
|
||||
pub fn checked_sub(&self, duration: Duration) -> Option<Self> {
|
||||
let duration = convert_to_time_duration(duration);
|
||||
self.0.checked_sub(duration).map(|inner| SystemTime(inner))
|
||||
self.0.checked_sub(duration).map(SystemTime)
|
||||
}
|
||||
|
||||
/// Returns the duration since an earlier time. Return error if `earlier` is later than self.
|
||||
|
@ -140,7 +140,7 @@ impl Vmar<Rights> {
|
||||
/// The method requires the Dup right.
|
||||
pub fn dup(&self) -> Result<Self> {
|
||||
self.check_rights(Rights::DUP)?;
|
||||
Ok(Vmar(self.0.clone(), self.1.clone()))
|
||||
Ok(Vmar(self.0.clone(), self.1))
|
||||
}
|
||||
|
||||
/// Given a map size, returns the possible map address without doing actual allocation.
|
||||
|
@ -140,11 +140,7 @@ impl Vmar_ {
|
||||
}
|
||||
|
||||
fn is_root_vmar(&self) -> bool {
|
||||
if let Some(_) = self.parent.upgrade() {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
self.parent.upgrade().is_none()
|
||||
}
|
||||
|
||||
pub fn protect(&self, perms: VmPerms, range: Range<usize>) -> Result<()> {
|
||||
@ -165,7 +161,7 @@ impl Vmar_ {
|
||||
}
|
||||
}
|
||||
|
||||
for (_, child_vmar_) in &self.inner.lock().child_vmar_s {
|
||||
for child_vmar_ in self.inner.lock().child_vmar_s.values() {
|
||||
let child_vmar_range = child_vmar_.range();
|
||||
if is_intersected(&range, &child_vmar_range) {
|
||||
let intersected_range = get_intersected_range(&range, &child_vmar_range);
|
||||
@ -185,17 +181,17 @@ impl Vmar_ {
|
||||
assert!(protected_range.end <= self.base + self.size);
|
||||
|
||||
// The protected range should not interstect with any free region
|
||||
for (_, free_region) in &self.inner.lock().free_regions {
|
||||
if is_intersected(&free_region.range, &protected_range) {
|
||||
for free_region in self.inner.lock().free_regions.values() {
|
||||
if is_intersected(&free_region.range, protected_range) {
|
||||
return_errno_with_message!(Errno::EACCES, "protected range is not fully mapped");
|
||||
}
|
||||
}
|
||||
|
||||
// if the protected range intersects with child vmar_, child vmar_ is responsible to do the check.
|
||||
for (_, child_vmar_) in &self.inner.lock().child_vmar_s {
|
||||
for child_vmar_ in self.inner.lock().child_vmar_s.values() {
|
||||
let child_range = child_vmar_.range();
|
||||
if is_intersected(&child_range, &protected_range) {
|
||||
let intersected_range = get_intersected_range(&child_range, &protected_range);
|
||||
if is_intersected(&child_range, protected_range) {
|
||||
let intersected_range = get_intersected_range(&child_range, protected_range);
|
||||
child_vmar_.check_protected_range(&intersected_range)?;
|
||||
}
|
||||
}
|
||||
@ -263,7 +259,7 @@ impl Vmar_ {
|
||||
inner.child_vmar_s.clear();
|
||||
inner.free_regions.append(&mut free_regions);
|
||||
|
||||
for (_, vm_mapping) in &inner.vm_mappings {
|
||||
for vm_mapping in inner.vm_mappings.values() {
|
||||
vm_mapping.unmap(&vm_mapping.range(), true)?;
|
||||
let free_region = FreeRegion::new(vm_mapping.range());
|
||||
free_regions.insert(free_region.start(), free_region);
|
||||
@ -296,7 +292,7 @@ impl Vmar_ {
|
||||
|
||||
let mut mappings_to_remove = BTreeSet::new();
|
||||
let mut mappings_to_append = BTreeMap::new();
|
||||
for (_, vm_mapping) in &inner.vm_mappings {
|
||||
for vm_mapping in inner.vm_mappings.values() {
|
||||
let vm_mapping_range = vm_mapping.range();
|
||||
if is_intersected(&vm_mapping_range, &range) {
|
||||
let intersected_range = get_intersected_range(&vm_mapping_range, &range);
|
||||
@ -501,7 +497,7 @@ impl Vmar_ {
|
||||
|
||||
fn check_vmo_overwrite(&self, vmo_range: Range<usize>, can_overwrite: bool) -> Result<()> {
|
||||
let inner = self.inner.lock();
|
||||
for (_, child_vmar) in &inner.child_vmar_s {
|
||||
for child_vmar in inner.child_vmar_s.values() {
|
||||
let child_vmar_range = child_vmar.range();
|
||||
if is_intersected(&vmo_range, &child_vmar_range) {
|
||||
return_errno_with_message!(
|
||||
@ -578,7 +574,7 @@ impl Vmar_ {
|
||||
}
|
||||
drop(inner);
|
||||
self.trim_existing_mappings(map_range)?;
|
||||
return Ok(offset);
|
||||
Ok(offset)
|
||||
} else {
|
||||
// Otherwise, the vmo in a single region
|
||||
let (free_region_base, offset) =
|
||||
@ -591,7 +587,7 @@ impl Vmar_ {
|
||||
regions_after_split.into_iter().for_each(|region| {
|
||||
inner.free_regions.insert(region.start(), region);
|
||||
});
|
||||
return Ok(offset);
|
||||
Ok(offset)
|
||||
}
|
||||
}
|
||||
|
||||
@ -609,7 +605,7 @@ impl Vmar_ {
|
||||
let mut inner = self.inner.lock();
|
||||
let mut mappings_to_remove = BTreeSet::new();
|
||||
let mut mappings_to_append = BTreeMap::new();
|
||||
for (_, vm_mapping) in &inner.vm_mappings {
|
||||
for vm_mapping in inner.vm_mappings.values() {
|
||||
vm_mapping.trim_mapping(
|
||||
&trim_range,
|
||||
&mut mappings_to_remove,
|
||||
|
@ -270,7 +270,7 @@ impl VmMapping {
|
||||
let map_to_addr = self.map_to_addr();
|
||||
let map_size = self.map_size();
|
||||
let range = self.range();
|
||||
if !is_intersected(&range, &trim_range) {
|
||||
if !is_intersected(&range, trim_range) {
|
||||
return Ok(());
|
||||
}
|
||||
if trim_range.start <= map_to_addr && trim_range.end >= map_to_addr + map_size {
|
||||
@ -334,7 +334,7 @@ impl VmMappingInner {
|
||||
let map_addr = self.page_map_addr(page_idx);
|
||||
|
||||
let vm_perm = {
|
||||
let mut perm = self.page_perms.get(&page_idx).unwrap().clone();
|
||||
let mut perm = *self.page_perms.get(&page_idx).unwrap();
|
||||
if is_readonly {
|
||||
debug_assert!(vmo.is_cow_child());
|
||||
perm -= VmPerm::W;
|
||||
@ -345,7 +345,7 @@ impl VmMappingInner {
|
||||
let vm_map_options = {
|
||||
let mut options = VmMapOptions::new();
|
||||
options.addr(Some(map_addr));
|
||||
options.perm(vm_perm.clone());
|
||||
options.perm(vm_perm);
|
||||
options
|
||||
};
|
||||
|
||||
@ -440,8 +440,8 @@ impl VmMappingInner {
|
||||
|
||||
self.map_to_addr = vaddr;
|
||||
let old_vmo_offset = self.vmo_offset;
|
||||
self.vmo_offset = self.vmo_offset + trim_size;
|
||||
self.map_size = self.map_size - trim_size;
|
||||
self.vmo_offset += trim_size;
|
||||
self.map_size -= trim_size;
|
||||
for page_idx in old_vmo_offset / PAGE_SIZE..self.vmo_offset / PAGE_SIZE {
|
||||
self.page_perms.remove(&page_idx);
|
||||
if self.mapped_pages.remove(&page_idx) {
|
||||
@ -477,7 +477,7 @@ impl VmMappingInner {
|
||||
fn check_perm(&self, page_idx: &usize, perm: &VmPerm) -> Result<()> {
|
||||
let page_perm = self
|
||||
.page_perms
|
||||
.get(&page_idx)
|
||||
.get(page_idx)
|
||||
.ok_or(Error::with_message(Errno::EINVAL, "invalid page idx"))?;
|
||||
|
||||
if !page_perm.contains(*perm) {
|
||||
@ -637,15 +637,15 @@ impl<R1, R2> VmarMapOptions<R1, R2> {
|
||||
fn check_overwrite(&self) -> Result<()> {
|
||||
if self.can_overwrite {
|
||||
// if can_overwrite is set, the offset cannot be None
|
||||
debug_assert!(self.offset != None);
|
||||
if self.offset == None {
|
||||
debug_assert!(self.offset.is_some());
|
||||
if self.offset.is_none() {
|
||||
return_errno_with_message!(
|
||||
Errno::EINVAL,
|
||||
"offset can not be none when can overwrite is true"
|
||||
);
|
||||
}
|
||||
}
|
||||
if self.offset == None {
|
||||
if self.offset.is_none() {
|
||||
// if does not specify the offset, we assume the map can always find suitable free region.
|
||||
// FIXME: is this always true?
|
||||
return Ok(());
|
||||
|
@ -133,7 +133,7 @@ impl Vmo<Rights> {
|
||||
/// The method requires the Dup right.
|
||||
pub fn dup(&self) -> Result<Self> {
|
||||
self.check_rights(Rights::DUP)?;
|
||||
Ok(Self(self.0.clone(), self.1.clone()))
|
||||
Ok(Self(self.0.clone(), self.1))
|
||||
}
|
||||
|
||||
/// Restricts the access rights given the mask.
|
||||
|
@ -230,7 +230,7 @@ impl VmoInner {
|
||||
}
|
||||
|
||||
fn should_share_frame_with_parent(&self, write_page: bool) -> bool {
|
||||
!self.is_cow || (self.is_cow && !write_page)
|
||||
!self.is_cow || !write_page
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ impl Vmo_ {
|
||||
}
|
||||
|
||||
pub fn flags(&self) -> VmoFlags {
|
||||
self.flags.clone()
|
||||
self.flags
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ impl<R: TRights> Vmo<TRightSet<R>> {
|
||||
/// The method requires the Dup right.
|
||||
#[require(R > Dup)]
|
||||
pub fn dup(&self) -> Result<Self> {
|
||||
Ok(Vmo(self.0.clone(), self.1.clone()))
|
||||
Ok(Vmo(self.0.clone(), self.1))
|
||||
}
|
||||
|
||||
/// Strict the access rights.
|
||||
|
Reference in New Issue
Block a user