refactor: fix warnings

This commit is contained in:
Mark Poliakov 2021-11-30 09:55:13 +02:00
parent 4c3374de36
commit 4ffbb8c115
30 changed files with 137 additions and 94 deletions

View File

@ -1,9 +1,6 @@
use crate::{BlockAllocator, Bvec, FileInode};
use alloc::boxed::Box;
use libsys::{
error::Errno,
stat::{DirectoryEntry, OpenFlags, Stat},
};
use libsys::{error::Errno, stat::Stat};
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef};
pub struct DirInode<A: BlockAllocator + Copy + 'static> {
@ -40,7 +37,7 @@ impl<A: BlockAllocator + Copy + 'static> VnodeImpl for DirInode<A> {
Ok(Stat {
size: 0,
blksize: 4096,
mode: props.mode
mode: props.mode,
})
}
}

View File

@ -19,6 +19,7 @@ pub trait CharDevice {
/// Performs a TTY control request
fn ioctl(&self, cmd: IoctlCmd, ptr: usize, lim: usize) -> Result<usize, Errno>;
/// Returns `true` if the device is ready for an operation
fn is_ready(&self, write: bool) -> Result<bool, Errno>;
}

View File

@ -98,7 +98,9 @@ impl File {
/// File has to be closed on execve() calls
pub const CLOEXEC: u32 = 1 << 2;
/// Special position for cache-readdir: "." entry
pub const POS_CACHE_DOT: usize = usize::MAX - 1;
/// Special position for cache-readdir: ".." entry
pub const POS_CACHE_DOT_DOT: usize = usize::MAX;
/// Constructs a new file handle for a regular file
@ -123,6 +125,7 @@ impl File {
self.flags & Self::CLOEXEC != 0
}
/// Returns `true` if the file is ready for an operation
pub fn is_ready(&self, write: bool) -> Result<bool, Errno> {
match &self.inner {
FileInner::Normal(inner) => inner.vnode.is_ready(write),
@ -169,6 +172,7 @@ impl File {
Ok(offset + count)
}
/// Reads directory entries into the target buffer
pub fn readdir(&mut self, entries: &mut [DirectoryEntry]) -> Result<usize, Errno> {
match &mut self.inner {
FileInner::Normal(inner) => {

View File

@ -10,7 +10,9 @@ use libsys::{
pub struct Ioctx {
root: VnodeRef,
cwd: VnodeRef,
/// Process user ID
pub uid: UserId,
/// Process group ID
pub gid: GroupId,
}
@ -123,6 +125,7 @@ impl Ioctx {
node.open(opts)
}
/// Changes current working directory of the process
pub fn chdir(&mut self, path: &str) -> Result<(), Errno> {
let node = self.find(None, path, true)?;
if !node.is_directory() {

View File

@ -31,6 +31,7 @@ pub(crate) struct TreeNode {
/// File property cache struct
pub struct VnodeProps {
/// Node permissions and type
pub mode: FileMode,
}
@ -74,6 +75,7 @@ pub trait VnodeImpl {
/// Resizes the file storage if necessary.
fn write(&mut self, node: VnodeRef, pos: usize, data: &[u8]) -> Result<usize, Errno>;
/// Read directory entries into target buffer
fn readdir(
&mut self,
node: VnodeRef,
@ -87,6 +89,7 @@ pub trait VnodeImpl {
/// Reports the size of this filesystem object in bytes
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno>;
/// Returns `true` if node is ready for an operation
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno>;
/// Performs filetype-specific request
@ -104,7 +107,9 @@ impl Vnode {
/// be seeked to arbitrary offsets
pub const SEEKABLE: u32 = 1 << 0;
/// If set, readdir() uses only in-memory node tree
pub const CACHE_READDIR: u32 = 1 << 1;
/// If set, stat() uses only in-memory stat data
pub const CACHE_STAT: u32 = 1 << 2;
/// Constructs a new [Vnode], wrapping it in [Rc]. The resulting node
@ -178,6 +183,7 @@ impl Vnode {
self.kind
}
/// Returns flags of the vnode
#[inline(always)]
pub const fn flags(&self) -> u32 {
self.flags
@ -476,6 +482,7 @@ impl Vnode {
}
}
/// Returns `true` if the node is ready for operation
pub fn is_ready(self: &VnodeRef, write: bool) -> Result<bool, Errno> {
if let Some(ref mut data) = *self.data() {
data.is_ready(self.clone(), write)
@ -484,6 +491,7 @@ impl Vnode {
}
}
/// Checks if given [Ioctx] has `access` permissions to the vnode
pub fn check_access(&self, _ioctx: &Ioctx, access: AccessMode) -> Result<(), Errno> {
let props = self.props.borrow();
let mode = props.mode;

View File

@ -28,7 +28,6 @@ pub struct Gic {
gicd: InitOnce<Gicd>,
gicd_base: usize,
gicc_base: usize,
scheduler_irq: IrqNumber,
table: IrqSafeSpinLock<[Option<&'static (dyn IntSource + Sync)>; MAX_IRQ]>,
}
@ -124,13 +123,12 @@ impl Gic {
/// # Safety
///
/// Does not perform `gicd_base` and `gicc_base` validation.
pub const unsafe fn new(gicd_base: usize, gicc_base: usize, scheduler_irq: IrqNumber) -> Self {
pub const unsafe fn new(gicd_base: usize, gicc_base: usize) -> Self {
Self {
gicc: InitOnce::new(),
gicd: InitOnce::new(),
gicd_base,
gicc_base,
scheduler_irq,
table: IrqSafeSpinLock::new([None; MAX_IRQ]),
}
}

View File

@ -78,6 +78,6 @@ pub fn intc() -> &'static impl IntController<IrqNumber = IrqNumber> {
static UART0: Pl011 = unsafe { Pl011::new(UART0_BASE, UART0_IRQ) };
static RTC: Pl031 = unsafe { Pl031::new(RTC_BASE, RTC_IRQ) };
static GIC: Gic = unsafe { Gic::new(GICD_BASE, GICC_BASE, LOCAL_TIMER_IRQ) };
static GIC: Gic = unsafe { Gic::new(GICD_BASE, GICC_BASE) };
static PCIE: GenericPcieHost = unsafe { GenericPcieHost::new(ECAM_BASE, 8) };
static LOCAL_TIMER: GenericTimer = GenericTimer::new(LOCAL_TIMER_IRQ);

View File

@ -114,7 +114,7 @@ macro_rules! errorln {
}
#[doc(hidden)]
pub fn _debug(level: Level, args: fmt::Arguments) {
pub fn _debug(_level: Level, args: fmt::Arguments) {
use crate::arch::machine;
use fmt::Write;

View File

@ -34,6 +34,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
/// Returns a reference to character device's ring buffer
fn ring(&self) -> &CharRing<N>;
/// Returns `true` if the TTY is ready for an operation
fn is_ready(&self, write: bool) -> Result<bool, Errno> {
let ring = self.ring();
if write {
@ -265,6 +266,7 @@ impl<const N: usize> CharRing<N> {
}
}
/// Returns `true` if a character/line is available for reception
pub fn is_readable(&self) -> bool {
let inner = self.inner.lock();
let config = self.config.lock();

View File

@ -28,6 +28,7 @@ unsafe impl BlockAllocator for MemfsBlockAlloc {
}
}
/// Creates a filesystem instance based on `options`
pub fn create_filesystem(options: &MountOptions) -> Result<VnodeRef, Errno> {
let fs_name = options.fs.unwrap();

View File

@ -210,6 +210,9 @@ impl Space {
}
}
/// Translates a virtual address into a corresponding physical one.
///
/// Only works for 4K pages atm.
// TODO extract attributes
pub fn translate(&mut self, virt: usize) -> Result<usize, Errno> {
let l0i = virt >> 30;
@ -264,6 +267,8 @@ impl Space {
Ok(())
}
/// Allocates a contiguous region from the address space and maps
/// physical pages to it
pub fn allocate(
&mut self,
start: usize,
@ -288,6 +293,8 @@ impl Space {
Err(Errno::OutOfMemory)
}
/// Removes a single 4K page mapping from the table and
/// releases the underlying physical memory
pub fn unmap_single(&mut self, page: usize) -> Result<(), Errno> {
let l0i = page >> 30;
let l1i = (page >> 21) & 0x1FF;
@ -304,7 +311,7 @@ impl Space {
let phys = unsafe { entry.address_unchecked() };
unsafe {
phys::free_page(phys);
phys::free_page(phys)?;
}
l2_table[l2i] = Entry::invalid();
@ -317,6 +324,7 @@ impl Space {
Ok(())
}
/// Releases a range of virtual pages and their corresponding physical pages
pub fn free(&mut self, start: usize, len: usize) -> Result<(), Errno> {
for i in 0..len {
self.unmap_single(start + i * 0x1000)?;

View File

@ -22,25 +22,30 @@ impl ProcessIo {
Ok(dst)
}
/// Sets controlling terminal for the process
pub fn set_ctty(&mut self, node: VnodeRef) {
assert_eq!(node.kind(), VnodeKind::Char);
self.ctty = Some(node);
}
/// Returns current controlling terminal of the process
pub fn ctty(&mut self) -> Option<VnodeRef> {
self.ctty.clone()
}
/// Returns user ID of the process
#[inline(always)]
pub fn uid(&self) -> UserId {
self.ioctx.as_ref().unwrap().uid
}
/// Returns group ID of the process
#[inline(always)]
pub fn gid(&self) -> GroupId {
self.ioctx.as_ref().unwrap().gid
}
/// Changes (if permitted) user ID of the process
#[inline(always)]
pub fn set_uid(&mut self, uid: UserId) -> Result<(), Errno> {
let old_uid = self.uid();
@ -54,6 +59,7 @@ impl ProcessIo {
}
}
/// Changes (if permitted) group ID of the process
#[inline(always)]
pub fn set_gid(&mut self, gid: GroupId) -> Result<(), Errno> {
let old_gid = self.gid();
@ -67,6 +73,7 @@ impl ProcessIo {
}
}
/// Clones a file descriptor into an available slot or, if specified, requested one
pub fn duplicate_file(&mut self, src: FileDescriptor, dst: Option<FileDescriptor>) -> Result<FileDescriptor, Errno> {
let file_ref = self.file(src)?;
if let Some(dst) = dst {

View File

@ -20,25 +20,6 @@ pub mod sched;
pub use sched::Scheduler;
pub(self) use sched::SCHED;
// macro_rules! spawn {
// (fn ($dst_arg:ident : usize) $body:block, $src_arg:expr) => {{
// #[inline(never)]
// extern "C" fn __inner_func($dst_arg : usize) -> ! {
// let __res = $body;
// {
// #![allow(unreachable_code)]
// SCHED.current_process().exit(__res);
// panic!();
// }
// }
//
// let __proc = $crate::proc::Process::new_kernel(__inner_func, $src_arg).unwrap();
// $crate::proc::SCHED.enqueue(__proc.id());
// }};
//
// (fn () $body:block) => (spawn!(fn (_arg: usize) $body, 0usize))
// }
/// Performs a task switch.
///
/// See [Scheduler::switch]
@ -46,12 +27,6 @@ pub fn switch() {
SCHED.switch(false);
}
///
pub fn process(id: Pid) -> ProcessRef {
PROCESSES.lock().get(&id).unwrap().clone()
}
/// Global list of all processes in the system
pub(self) static PROCESSES: IrqSafeSpinLock<BTreeMap<Pid, ProcessRef>> =
IrqSafeSpinLock::new(BTreeMap::new());

View File

@ -8,18 +8,16 @@ use crate::mem::{
use crate::proc::{
wait::Wait, Context, ProcessIo, Thread, ThreadRef, ThreadState, PROCESSES, SCHED,
};
use crate::sync::{IrqSafeSpinLock, IrqSafeSpinLockGuard};
use crate::sync::IrqSafeSpinLock;
use alloc::{rc::Rc, vec::Vec};
use core::alloc::Layout;
use core::sync::atomic::{AtomicU32, Ordering};
use libsys::{
error::Errno,
mem::memcpy,
proc::{ExitCode, Pid},
signal::Signal,
mem::memcpy,
ProgramArgs,
};
use vfs::{VnodeKind, VnodeRef};
/// Wrapper type for a process struct reference
pub type ProcessRef = Rc<Process>;
@ -58,39 +56,47 @@ impl Process {
const USTACK_VIRT_TOP: usize = 0x100000000;
const USTACK_PAGES: usize = 4;
/// Returns the process ID
#[inline]
pub fn id(&self) -> Pid {
self.inner.lock().id
}
/// Returns the process session ID
#[inline]
pub fn sid(&self) -> Pid {
self.inner.lock().sid
}
/// Returns parent's [Pid]
#[inline]
pub fn pgid(&self) -> Pid {
self.inner.lock().pgid
}
/// Returns parent's [Pid]
#[inline]
pub fn ppid(&self) -> Option<Pid> {
self.inner.lock().ppid
}
/// Sets a new group id for the process
pub fn set_pgid(&self, pgid: Pid) {
self.inner.lock().pgid = pgid;
}
/// Sets a new session id for the process
pub fn set_sid(&self, sid: Pid) {
self.inner.lock().sid = sid;
}
/// Returns [Rc]-reference to current process
#[inline]
pub fn current() -> ProcessRef {
Thread::current().owner().unwrap()
}
/// Executes a closure performing manipulations on the process address space
#[inline]
pub fn manipulate_space<R, F>(&self, f: F) -> R
where
@ -99,6 +105,7 @@ impl Process {
f(self.inner.lock().space.as_mut().unwrap())
}
/// Creates a new kernel process
pub fn new_kernel(entry: extern "C" fn(usize) -> !, arg: usize) -> Result<ProcessRef, Errno> {
let id = new_kernel_pid();
let thread = Thread::new_kernel(Some(id), entry, arg)?;
@ -126,6 +133,7 @@ impl Process {
Ok(res)
}
/// Adds all of the process threads to scheduler queue
pub fn enqueue(&self) {
let inner = self.inner.lock();
for &tid in inner.threads.iter() {
@ -168,12 +176,14 @@ impl Process {
}
}
/// Immediately delivers a signal to requested thread
pub fn enter_fault_signal(&self, thread: ThreadRef, signal: Signal) {
let mut lock = self.inner.lock();
let ttbr0 = lock.space.as_mut().unwrap().address_phys() | ((lock.id.asid() as usize) << 48);
thread.enter_signal(signal, ttbr0);
}
/// Crates a new thread in the process
pub fn new_user_thread(&self, entry: usize, stack: usize, arg: usize) -> Result<u32, Errno> {
let mut lock = self.inner.lock();
@ -264,6 +274,8 @@ impl Process {
}
}
/// Terminates a thread of the process. If the thread is the only
/// one remaining, process itself is exited (see [Process::exit])
pub fn exit_thread(thread: ThreadRef, status: ExitCode) {
let switch = {
let switch = thread.state() == ThreadState::Running;
@ -337,11 +349,11 @@ impl Process {
phys
} else {
let page = phys::alloc_page(PageUsage::UserPrivate)?;
let flags = MapAttributes::SH_OUTER |
MapAttributes::NOT_GLOBAL |
MapAttributes::UXN |
MapAttributes::PXN |
MapAttributes::AP_BOTH_READONLY;
let flags = MapAttributes::SH_OUTER
| MapAttributes::NOT_GLOBAL
| MapAttributes::UXN
| MapAttributes::PXN
| MapAttributes::AP_BOTH_READONLY;
space.map(page_virt, page, flags)?;
page
};
@ -361,17 +373,21 @@ impl Process {
phys
} else {
let page = phys::alloc_page(PageUsage::UserPrivate)?;
let flags = MapAttributes::SH_OUTER |
MapAttributes::NOT_GLOBAL |
MapAttributes::UXN |
MapAttributes::PXN |
MapAttributes::AP_BOTH_READONLY;
let flags = MapAttributes::SH_OUTER
| MapAttributes::NOT_GLOBAL
| MapAttributes::UXN
| MapAttributes::PXN
| MapAttributes::AP_BOTH_READONLY;
space.map(page_virt, page, flags)?;
page
};
unsafe {
memcpy((mem::virtualize(page_phys) + (dst % 4096)) as *mut u8, src.as_ptr(), src.len());
memcpy(
(mem::virtualize(page_phys) + (dst % 4096)) as *mut u8,
src.as_ptr(),
src.len(),
);
}
Ok(())
}
@ -405,7 +421,7 @@ impl Process {
argc: argv.len(),
argv: base + argv_offset,
storage: base,
size: offset + core::mem::size_of::<ProgramArgs>()
size: offset + core::mem::size_of::<ProgramArgs>(),
};
Self::write_paged(space, base + offset, data)?;

View File

@ -48,14 +48,6 @@ impl Scheduler {
self.inner.get().lock().queue.retain(|&p| p != tid)
}
pub fn debug(&self) {
let lock = self.inner.get().lock();
debugln!("Scheduler queue:");
for &tid in lock.queue.iter() {
debugln!("TID: {:?}", tid);
}
}
/// Performs initial process entry.
///
/// # Safety
@ -132,6 +124,7 @@ impl Scheduler {
}
}
/// Returns a [Rc]-reference to currently running Thread
pub fn current_thread(&self) -> ThreadRef {
let inner = self.inner.get().lock();
let id = inner.current.unwrap();

View File

@ -1,5 +1,10 @@
//! Facilities for controlling threads - smallest units of
//! execution in the operating system
use crate::arch::aarch64::exception::ExceptionFrame;
use crate::proc::{wait::{Wait, WaitStatus}, Process, ProcessRef, SCHED, THREADS};
use crate::proc::{
wait::{Wait, WaitStatus},
Process, ProcessRef, SCHED, THREADS,
};
use crate::sync::IrqSafeSpinLock;
use crate::util::InitOnce;
use alloc::rc::Rc;
@ -13,6 +18,7 @@ use libsys::{
pub use crate::arch::platform::context::{self, Context};
/// Convenience wrapper for [Thread] references
pub type ThreadRef = Rc<Thread>;
/// List of possible process states
@ -38,6 +44,7 @@ struct ThreadInner {
signal_stack: usize,
}
/// Thread control data
pub struct Thread {
inner: IrqSafeSpinLock<ThreadInner>,
exit_wait: Wait,
@ -48,21 +55,25 @@ pub struct Thread {
}
impl Thread {
/// Returns currently active thread [Rc]-reference
#[inline]
pub fn current() -> ThreadRef {
SCHED.current_thread()
}
/// Returns a reference to thread `tid`, if it exists
#[inline]
pub fn get(tid: u32) -> Option<ThreadRef> {
THREADS.lock().get(&tid).cloned()
}
/// Returns the owner process
#[inline]
pub fn owner(&self) -> Option<ProcessRef> {
self.inner.lock().owner.and_then(Process::get)
}
/// Returns [Pid] of the owner process
pub fn owner_id(&self) -> Option<Pid> {
self.inner.lock().owner
}
@ -127,6 +138,7 @@ impl Thread {
Ok(res)
}
/// Creates a fork thread cloning `frame` context
pub fn fork(
owner: Option<Pid>,
frame: &ExceptionFrame,
@ -155,6 +167,7 @@ impl Thread {
Ok(res)
}
/// Returns the thread ID
#[inline]
pub fn id(&self) -> u32 {
self.inner.lock().id
@ -230,6 +243,7 @@ impl Thread {
lock.wait_status = WaitStatus::Pending;
}
/// Suspends current thread until thread `tid` terminates
pub fn waittid(tid: u32) -> Result<(), Errno> {
loop {
let thread = THREADS
@ -247,17 +261,20 @@ impl Thread {
}
}
/// Updates pending wait status
pub fn set_wait_status(&self, status: WaitStatus) {
let mut lock = self.inner.lock();
lock.wait_status = status;
}
/// Resets wait channel back to initial state
pub fn reset_wait(&self) {
let mut lock = self.inner.lock();
lock.pending_wait = None;
lock.wait_status = WaitStatus::Done;
}
/// Returns status of the thread's pending wait
pub fn wait_status(&self) -> WaitStatus {
self.inner.lock().wait_status
}
@ -279,11 +296,13 @@ impl Thread {
}
}
/// Returns the thread state
#[inline]
pub fn state(&self) -> State {
self.inner.lock().state
}
/// Sets the thread's owner process ID
pub fn set_owner(&self, pid: Pid) {
self.inner.lock().owner = Some(pid);
}
@ -295,6 +314,7 @@ impl Thread {
lock.signal_stack = stack;
}
/// Sets up a context for signal handler
pub fn setup_signal(self: ThreadRef, signal: Signal, ttbr0: usize) {
if self
.signal_pending
@ -312,7 +332,6 @@ impl Thread {
}
let signal_ctx = unsafe { &mut *self.signal_ctx.get() };
let src_ctx = self.ctx.get();
debugln!(
"Signal entry: tid={}, pc={:#x}, sp={:#x}, ttbr0={:#x}",
@ -330,7 +349,6 @@ impl Thread {
lock.signal_stack,
);
}
}
/// Switches process main thread to a signal handler
@ -346,6 +364,7 @@ impl Thread {
}
}
/// Interrupts pending wait (from signal routines)
pub fn interrupt_wait(&self, enqueue: bool) {
let mut lock = self.inner.lock();
let tid = lock.id;
@ -356,6 +375,8 @@ impl Thread {
}
}
/// Cleans up any resources of the thread and aborts
/// pending wait, if any
pub fn terminate(&self, status: ExitCode) {
let mut lock = self.inner.lock();
lock.state = State::Finished;
@ -376,6 +397,7 @@ impl Drop for Thread {
}
}
/// Allocates a new thread ID
pub fn new_tid() -> u32 {
static LAST: AtomicU32 = AtomicU32::new(1);
let id = LAST.fetch_add(1, Ordering::Relaxed);

View File

@ -12,13 +12,18 @@ use libsys::{error::Errno, stat::FdSet};
/// waiting for some event to happen.
pub struct Wait {
queue: IrqSafeSpinLock<LinkedList<u32>>,
#[allow(dead_code)]
name: &'static str
}
/// Status of a (possibly) pending wait
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum WaitStatus {
/// In progress
Pending,
/// Wait was interrupted by a signal
Interrupted,
/// Channel reported data available
Done,
}
@ -28,6 +33,8 @@ struct Timeout {
}
static TICK_LIST: IrqSafeSpinLock<LinkedList<Timeout>> = IrqSafeSpinLock::new(LinkedList::new());
/// Global wait channel for blocking on select. Gets notified
/// of ANY I/O operations available, so not very efficient.
pub static WAIT_SELECT: Wait = Wait::new("select");
/// Checks for any timed out wait channels and interrupts them
@ -63,6 +70,8 @@ pub fn sleep(timeout: Duration, remaining: &mut Duration) -> Result<(), Errno> {
}
}
/// Suspends current process until some file descriptor
/// signals data available
pub fn select(
thread: ThreadRef,
mut rfds: Option<&mut FdSet>,
@ -119,6 +128,7 @@ impl Wait {
}
}
/// Interrupt wait pending on the channel
pub fn abort(&self, tid: u32, enqueue: bool) {
let mut queue = self.queue.lock();
let mut tick_lock = TICK_LIST.lock();

View File

@ -36,6 +36,7 @@ fn is_el0_accessible(virt: usize, write: bool) -> bool {
res & 1 == 0
}
/// Checks given argument and interprets it as a `T` reference
pub fn struct_ref<'a, T>(base: usize) -> Result<&'a T, Errno> {
let layout = Layout::new::<T>();
if base % layout.align() != 0 {
@ -49,6 +50,7 @@ pub fn struct_ref<'a, T>(base: usize) -> Result<&'a T, Errno> {
Ok(unsafe { &*(bytes.as_ptr() as *const T) })
}
/// Checks given argument and interprets it as a `T` mutable reference
pub fn struct_mut<'a, T>(base: usize) -> Result<&'a mut T, Errno> {
let layout = Layout::new::<T>();
if base % layout.align() != 0 {
@ -62,6 +64,7 @@ pub fn struct_mut<'a, T>(base: usize) -> Result<&'a mut T, Errno> {
Ok(unsafe { &mut *(bytes.as_mut_ptr() as *mut T) })
}
/// Checks given argument and interprets it as a `T` array buffer of size `count`
pub fn struct_buf_ref<'a, T>(base: usize, count: usize) -> Result<&'a [T], Errno> {
let layout = Layout::array::<T>(count).unwrap();
if base % layout.align() != 0 {
@ -75,6 +78,7 @@ pub fn struct_buf_ref<'a, T>(base: usize, count: usize) -> Result<&'a [T], Errno
Ok(unsafe { core::slice::from_raw_parts(bytes.as_ptr() as *const T, count) })
}
/// Checks given argument and interprets it as a `T` array buffer of size `count`
pub fn struct_buf_mut<'a, T>(base: usize, count: usize) -> Result<&'a mut [T], Errno> {
let layout = Layout::array::<T>(count).unwrap();
if base % layout.align() != 0 {
@ -88,6 +92,7 @@ pub fn struct_buf_mut<'a, T>(base: usize, count: usize) -> Result<&'a mut [T], E
Ok(unsafe { core::slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut T, count) })
}
/// Checks given argument and interprets it as a `Option<&'a T>`
pub fn option_struct_ref<'a, T>(base: usize) -> Result<Option<&'a T>, Errno> {
if base == 0 {
Ok(None)
@ -96,6 +101,7 @@ pub fn option_struct_ref<'a, T>(base: usize) -> Result<Option<&'a T>, Errno> {
}
}
/// Checks given argument and interprets it as a `Option<&'a mut T>`
pub fn option_struct_mut<'a, T>(base: usize) -> Result<Option<&'a mut T>, Errno> {
if base == 0 {
Ok(None)
@ -104,6 +110,8 @@ pub fn option_struct_mut<'a, T>(base: usize) -> Result<Option<&'a mut T>, Errno>
}
}
/// Validates that the argument pointer is accessible for requested operation
/// for current process
pub fn validate_ptr(base: usize, len: usize, write: bool) -> Result<(), Errno> {
if base > mem::KERNEL_OFFSET || base + len > mem::KERNEL_OFFSET {
invalid_memory!(
@ -144,16 +152,19 @@ pub fn validate_ptr(base: usize, len: usize, write: bool) -> Result<(), Errno> {
Ok(())
}
/// Checks given argument and interprets it as a byte buffer
pub fn buf_ref<'a>(base: usize, len: usize) -> Result<&'a [u8], Errno> {
validate_ptr(base, len, false)?;
Ok(unsafe { core::slice::from_raw_parts(base as *const u8, len) })
}
/// Checks given argument and interprets it as a mutable byte buffer
pub fn buf_mut<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Errno> {
validate_ptr(base, len, true)?;
Ok(unsafe { core::slice::from_raw_parts_mut(base as *mut u8, len) })
}
/// Checks possibly NULL given argument and interprets it as a byte buffer
pub fn option_buf_ref<'a>(base: usize, len: usize) -> Result<Option<&'a [u8]>, Errno> {
if base == 0 {
Ok(None)
@ -162,6 +173,7 @@ pub fn option_buf_ref<'a>(base: usize, len: usize) -> Result<Option<&'a [u8]>, E
}
}
/// Checks possibly NULL given argument and interprets it as a mutable byte buffer
pub fn option_buf_mut<'a>(base: usize, len: usize) -> Result<Option<&'a mut [u8]>, Errno> {
if base == 0 {
Ok(None)

View File

@ -14,7 +14,7 @@ use libsys::{
debug::TraceLevel,
error::Errno,
ioctl::IoctlCmd,
proc::{ExitCode, Pid, MemoryAccess, MemoryMap},
proc::{ExitCode, Pid, MemoryAccess},
signal::{Signal, SignalDestination},
stat::{
AccessMode, DirectoryEntry, FdSet, FileDescriptor, FileMode, GroupId, MountOptions,
@ -208,7 +208,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
return Err(Errno::InvalidArgument);
}
let acc = MemoryAccess::from_bits(args[2] as u32).ok_or(Errno::InvalidArgument)?;
let flags = MemoryAccess::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let _flags = MemoryAccess::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let mut attrs = MapAttributes::NOT_GLOBAL | MapAttributes::SH_OUTER | MapAttributes::PXN;
if !acc.contains(MemoryAccess::READ) {
@ -386,7 +386,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
let proc = Process::current();
let mut io = proc.io.lock();
if let Some(ctty) = io.ctty() {
if let Some(_ctty) = io.ctty() {
todo!();
}

View File

@ -472,5 +472,5 @@ pub fn sys_mmap(
#[inline(always)]
pub unsafe fn sys_munmap(addr: usize, len: usize) -> Result<(), Errno> {
Errno::from_syscall_unit(unsafe { syscall!(SystemCall::UnmapMemory, argn!(addr), argn!(len)) })
Errno::from_syscall_unit(syscall!(SystemCall::UnmapMemory, argn!(addr), argn!(len)))
}

View File

@ -274,8 +274,7 @@ impl fmt::Display for FileMode {
choose(self.contains(Self::OTHER_READ), 'r', '-'),
choose(self.contains(Self::OTHER_WRITE), 'w', '-'),
choose(self.contains(Self::OTHER_EXEC), 'x', '-'),
);
Ok(())
)
}
}

View File

@ -1,12 +1,9 @@
use core::alloc::{GlobalAlloc, Layout};
use core::mem::{size_of, MaybeUninit};
use core::ptr::null_mut;
use core::sync::atomic::{AtomicUsize, Ordering};
use libsys::{
calls::{sys_mmap, sys_munmap},
debug::TraceLevel,
error::Errno,
mem::memset,
proc::{MemoryAccess, MemoryMap},
};
use memoffset::offset_of;
@ -117,7 +114,7 @@ impl Zone {
unsafe fn zone_alloc(zone: &mut Zone, size: usize) -> *mut u8 {
assert_eq!(size & 15, 0);
let mut begin = ((zone as *mut _ as usize) + size_of::<Zone>()) as *mut Block;
let begin = ((zone as *mut _ as usize) + size_of::<Zone>()) as *mut Block;
let mut block = begin;
while !block.is_null() {
@ -168,6 +165,7 @@ unsafe fn alloc_from(list: &mut ZoneList, zone_size: usize, size: usize) -> *mut
if !ptr.is_null() {
return ptr;
}
zone = (&mut *zone).next;
}
let zone = match Zone::alloc(zone_size) {

View File

@ -1,4 +1,4 @@
use crate::io::{AsRawFd, Error, Read, Write};
use crate::io::{AsRawFd, Error, Read};
use libsys::{
calls::{sys_openat, sys_read, sys_close},
stat::{FileDescriptor, FileMode, OpenFlags},

View File

@ -28,7 +28,7 @@ pub trait AsRawFd {
fn as_raw_fd(&self) -> FileDescriptor;
}
pub fn tcgetpgrp(fd: FileDescriptor) -> Result<Pid, Errno> {
pub fn tcgetpgrp(_fd: FileDescriptor) -> Result<Pid, Errno> {
todo!()
}

View File

@ -3,8 +3,6 @@
#[macro_use]
extern crate libusr;
#[macro_use]
extern crate alloc;
use libusr::io::{self, Read, Write};
use libusr::file::File;
@ -19,7 +17,7 @@ fn do_cat<F: Read>(mut fd: F) -> Result<(), io::Error> {
break;
}
out.write(&buf[..count]);
out.write(&buf[..count])?;
}
Ok(())

View File

@ -3,10 +3,8 @@
#[macro_use]
extern crate libusr;
#[macro_use]
extern crate alloc;
use libusr::io::{self, Read, Write};
use libusr::io::{self, Read};
use libusr::file::File;
fn line_print(off: usize, line: &[u8]) {

View File

@ -6,7 +6,7 @@ extern crate libusr;
#[macro_use]
extern crate alloc;
use alloc::{borrow::ToOwned, string::String};
use alloc::borrow::ToOwned;
use libusr::sys::{
stat::{DirectoryEntry, FileMode, OpenFlags, Stat},
sys_close, sys_fstatat, sys_openat, sys_readdir, Errno,

View File

@ -107,7 +107,6 @@ fn main() -> i32 {
println!("Interrupt!");
continue;
}
_ => panic!(),
}
}
0

View File

@ -18,11 +18,9 @@ fn main() -> i32 {
)
.expect("Failed to mount devfs");
let pid = unsafe { libusr::sys::sys_fork().unwrap() };
if let Some(pid) = pid {
if let Some(pid) = unsafe { sys_fork().unwrap() } {
let mut status = 0;
libusr::sys::sys_waitpid(pid, &mut status).unwrap();
sys_waitpid(pid, &mut status).unwrap();
println!("Process {:?} exited with status {}", pid, status);
loop {
@ -31,7 +29,7 @@ fn main() -> i32 {
}
}
} else {
libusr::sys::sys_execve("/sbin/login", &["/sbin/login", "/dev/ttyS0"]).unwrap();
sys_execve("/sbin/login", &["/sbin/login", "/dev/ttyS0"]).unwrap();
loop {}
}
}

View File

@ -3,8 +3,6 @@
#[macro_use]
extern crate libusr;
#[macro_use]
extern crate alloc;
use libsys::{
calls::{
@ -96,7 +94,7 @@ fn login_as(uid: UserId, gid: GroupId, shell: &str) -> Result<(), Errno> {
// TODO baud rate and misc port settings
#[no_mangle]
fn main() -> i32 {
if !sys_getuid().is_root() {
if !sys_getuid().is_root() || !sys_getgid().is_root() {
panic!("This program must be run as root");
}
@ -143,9 +141,7 @@ fn main() -> i32 {
.expect("Password read failed");
if username == "root" && password == "toor" {
login_as(UserId::from(0), GroupId::from(0), "/bin/shell");
login_as(UserId::from(0), GroupId::from(0), "/bin/shell").unwrap();
}
}
0
}