refactor: fix clippy warnings
This commit is contained in:
parent
0a10b3c0b3
commit
00c368c36b
2
Makefile
2
Makefile
@ -121,7 +121,7 @@ doc-open:
|
||||
|
||||
clippy:
|
||||
cd kernel && cargo clippy $(CARGO_BUILD_OPTS)
|
||||
cd init && cargo clippy \
|
||||
cd user && cargo clippy \
|
||||
--target=../etc/$(ARCH)-osdev5.json \
|
||||
-Zbuild-std=core,alloc,compiler_builtins $(CARGO_COMMON_OPTS)
|
||||
|
||||
|
@ -20,6 +20,7 @@ pub trait CharDevice {
|
||||
/// will immediately return an error.
|
||||
fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, Errno>;
|
||||
|
||||
/// Performs a TTY control request
|
||||
fn ioctl(&self, cmd: IoctlCmd, ptr: usize, lim: usize) -> Result<usize, Errno>;
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@ pub trait VnodeImpl {
|
||||
/// Reports the size of this filesystem object in bytes
|
||||
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno>;
|
||||
|
||||
/// Performs filetype-specific request
|
||||
fn ioctl(
|
||||
&mut self,
|
||||
node: VnodeRef,
|
||||
|
@ -26,9 +26,12 @@ pub struct CharRing<const N: usize> {
|
||||
inner: IrqSafeSpinLock<CharRingInner<N>>,
|
||||
}
|
||||
|
||||
/// Generic teletype device interface
|
||||
pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
/// Returns a reference to character device's ring buffer
|
||||
fn ring(&self) -> &CharRing<N>;
|
||||
|
||||
/// Performs a TTY control request
|
||||
fn tty_ioctl(&self, cmd: IoctlCmd, ptr: usize, _len: usize) -> Result<usize, Errno> {
|
||||
match cmd {
|
||||
IoctlCmd::TtyGetAttributes => {
|
||||
@ -46,6 +49,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
}
|
||||
}
|
||||
|
||||
/// Processes and writes output an output byte
|
||||
fn line_send(&self, byte: u8) -> Result<(), Errno> {
|
||||
let config = self.ring().config.lock();
|
||||
|
||||
@ -56,6 +60,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
self.send(byte)
|
||||
}
|
||||
|
||||
/// Receives input bytes and processes them
|
||||
fn recv_byte(&self, mut byte: u8) {
|
||||
let ring = self.ring();
|
||||
let config = ring.config.lock();
|
||||
@ -96,7 +101,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
let ring = self.ring();
|
||||
let mut config = ring.config.lock();
|
||||
|
||||
if data.len() == 0 {
|
||||
if data.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
@ -104,7 +109,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
drop(config);
|
||||
let byte = ring.getc()?;
|
||||
data[0] = byte;
|
||||
return Ok(1);
|
||||
Ok(1)
|
||||
} else {
|
||||
let mut rem = data.len();
|
||||
let mut off = 0;
|
||||
@ -164,6 +169,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
}
|
||||
}
|
||||
|
||||
/// Processes and writes string bytes
|
||||
fn line_write(&self, data: &[u8]) -> Result<usize, Errno> {
|
||||
for &byte in data.iter() {
|
||||
self.line_send(byte)?;
|
||||
@ -171,6 +177,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
|
||||
Ok(data.len())
|
||||
}
|
||||
|
||||
/// Writes string bytes without any processing
|
||||
fn raw_write(&self, data: &[u8]) -> Result<usize, Errno> {
|
||||
for &byte in data.iter() {
|
||||
self.send(byte)?;
|
||||
|
@ -97,25 +97,28 @@ unsafe impl Manager for SimpleManager {
|
||||
|
||||
fn copy_cow_page(&mut self, src: usize) -> Result<usize, Errno> {
|
||||
let src_index = self.page_index(src);
|
||||
let page = &mut self.pages[src_index];
|
||||
let usage = page.usage;
|
||||
if usage != PageUsage::UserPrivate {
|
||||
panic!("CoW not available for non-UserPrivate pages: {:?}", usage);
|
||||
}
|
||||
let (usage, refcount) = {
|
||||
let page = &mut self.pages[src_index];
|
||||
let usage = page.usage;
|
||||
if usage != PageUsage::UserPrivate {
|
||||
panic!("CoW not available for non-UserPrivate pages: {:?}", usage);
|
||||
}
|
||||
let count = page.refcount;
|
||||
if count > 1 {
|
||||
page.refcount -= 1;
|
||||
}
|
||||
(usage, count)
|
||||
};
|
||||
|
||||
if page.refcount > 1 {
|
||||
page.refcount -= 1;
|
||||
drop(page);
|
||||
if refcount == 0 {
|
||||
Ok(src)
|
||||
} else {
|
||||
let dst_index = self.alloc_single_index(usage)?;
|
||||
let dst = (self.base_index + dst_index) * PAGE_SIZE;
|
||||
unsafe {
|
||||
memcpy(virtualize(dst) as *mut u8, virtualize(src) as *mut u8, 4096);
|
||||
}
|
||||
Ok(dst)
|
||||
} else {
|
||||
assert_eq!(page.refcount, 1);
|
||||
// No additional operations needed
|
||||
Ok(src)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,12 @@ pub unsafe fn free_page(page: usize) -> Result<(), Errno> {
|
||||
MANAGER.lock().as_mut().unwrap().free_page(page)
|
||||
}
|
||||
|
||||
/// Clones the source page.
|
||||
///
|
||||
/// If returned address is the same as `page`, this means
|
||||
/// `page`'s refcount has increased and the page is Copy-on-Write.
|
||||
/// This case has to be handled accordingly
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: accepts arbitrary `page` arguments
|
||||
@ -96,6 +102,12 @@ pub unsafe fn fork_page(page: usize) -> Result<usize, Errno> {
|
||||
MANAGER.lock().as_mut().unwrap().fork_page(page)
|
||||
}
|
||||
|
||||
/// Copies a Copy-on-Write page. If refcount is already 1,
|
||||
/// page does not need to be copied and the same address is returned.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: accepts arbitrary `page` arguments
|
||||
pub unsafe fn copy_cow_page(page: usize) -> Result<usize, Errno> {
|
||||
MANAGER.lock().as_mut().unwrap().copy_cow_page(page)
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ bitflags! {
|
||||
/// This page is used for device-MMIO mapping and uses MAIR attribute #1
|
||||
const DEVICE = 1 << 2;
|
||||
|
||||
/// Pages marked with this bit are Copy-on-Write
|
||||
const EX_COW = 1 << 55;
|
||||
|
||||
/// UXN bit -- if set, page may not be used for instruction fetching from EL0
|
||||
@ -209,6 +210,8 @@ impl Space {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to resolve a page fault at `virt` address by copying the
|
||||
/// underlying Copy-on-Write mapping (if any is present)
|
||||
pub fn try_cow_copy(&mut self, virt: usize) -> Result<(), Errno> {
|
||||
let virt = virt & !0xFFF;
|
||||
let l0i = virt >> 30;
|
||||
@ -284,6 +287,13 @@ impl Space {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Releases all the mappings from the address space. Frees all
|
||||
/// memory pages referenced by this space as well as those used for
|
||||
/// its paging tables.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: may invalidate currently active address space
|
||||
pub unsafe fn release(space: &mut Self) {
|
||||
for l0i in 0..512 {
|
||||
let l0_entry = space.0[l0i];
|
||||
|
@ -125,6 +125,11 @@ impl Pid {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Constructs [Pid] from raw [u32] value
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: does not check `num`
|
||||
pub const unsafe fn from_raw(num: u32) -> Self {
|
||||
Self(num)
|
||||
}
|
||||
@ -150,6 +155,7 @@ impl Process {
|
||||
SCHED.current_process()
|
||||
}
|
||||
|
||||
/// Returns process (if any) to which `pid` refers
|
||||
pub fn get(pid: Pid) -> Option<ProcessRef> {
|
||||
PROCESSES.lock().get(&pid).cloned()
|
||||
}
|
||||
@ -168,6 +174,7 @@ impl Process {
|
||||
(&mut *ctx).enter()
|
||||
}
|
||||
|
||||
/// Executes a function allowing mutation of the process address space
|
||||
#[inline]
|
||||
pub fn manipulate_space<F: FnOnce(&mut Space) -> Result<(), Errno>>(
|
||||
&self,
|
||||
|
@ -126,6 +126,7 @@ impl Scheduler {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the scheduler has been initialized
|
||||
pub fn is_ready() -> bool {
|
||||
SCHED.inner.is_initialized()
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ use crate::{
|
||||
ioctl::IoctlCmd,
|
||||
stat::{FileMode, OpenFlags, Stat},
|
||||
};
|
||||
use core::mem::size_of;
|
||||
|
||||
// TODO document the syscall ABI
|
||||
|
||||
@ -188,6 +187,9 @@ pub unsafe fn sys_waitpid(pid: u32, status: &mut i32) -> i32 {
|
||||
syscall!(abi::SYS_WAITPID, argn!(pid), argp!(status as *mut i32)) as i32
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// System call
|
||||
#[inline(always)]
|
||||
pub unsafe fn sys_ioctl(fd: u32, cmd: IoctlCmd, ptr: usize, len: usize) -> isize {
|
||||
syscall!(
|
||||
|
@ -5,22 +5,31 @@
|
||||
#[macro_use]
|
||||
extern crate libusr;
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let pid = unsafe { libusr::sys::sys_fork() };
|
||||
if pid < 0 {
|
||||
eprintln!("fork() failed");
|
||||
return -1;
|
||||
} else if pid == 0 {
|
||||
return unsafe { libusr::sys::sys_execve("/bin/shell") };
|
||||
} else {
|
||||
let mut status = 0;
|
||||
let res = unsafe { libusr::sys::sys_waitpid(pid as u32, &mut status) };
|
||||
if res == 0 {
|
||||
println!("Process {} exited with status {}", pid, status);
|
||||
} else {
|
||||
eprintln!("waitpid() failed");
|
||||
match pid.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
eprintln!("fork() failed");
|
||||
-1
|
||||
}
|
||||
Ordering::Equal => unsafe { libusr::sys::sys_execve("/bin/shell") },
|
||||
Ordering::Greater => {
|
||||
let mut status = 0;
|
||||
let res = unsafe { libusr::sys::sys_waitpid(pid as u32, &mut status) };
|
||||
if res == 0 {
|
||||
println!("Process {} exited with status {}", pid, status);
|
||||
} else {
|
||||
eprintln!("waitpid() failed");
|
||||
}
|
||||
|
||||
loop {
|
||||
unsafe {
|
||||
asm!("nop");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
|
@ -31,5 +31,5 @@ fn main() -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
0
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user