feature(fs): O_CREAT option
This commit is contained in:
+3
-3
@@ -3,7 +3,7 @@ use crate::fs::{devfs, MemfsBlockAlloc};
|
||||
use crate::mem;
|
||||
use crate::proc::{elf, Process};
|
||||
use memfs::Ramfs;
|
||||
use vfs::{FileMode, Filesystem, Ioctx};
|
||||
use vfs::{FileMode, Filesystem, Ioctx, OpenFlags};
|
||||
|
||||
#[inline(never)]
|
||||
pub extern "C" fn init_fn(_arg: usize) -> ! {
|
||||
@@ -28,7 +28,7 @@ pub extern "C" fn init_fn(_arg: usize) -> ! {
|
||||
let ioctx = Ioctx::new(root);
|
||||
|
||||
let node = ioctx.find(None, "/init", true).unwrap();
|
||||
let mut file = node.open().unwrap();
|
||||
let mut file = node.open(OpenFlags::O_RDONLY).unwrap();
|
||||
|
||||
proc.set_ioctx(ioctx);
|
||||
|
||||
@@ -43,7 +43,7 @@ pub extern "C" fn init_fn(_arg: usize) -> ! {
|
||||
|
||||
let mut io = proc.io.lock();
|
||||
// TODO fd cloning?
|
||||
io.place_file(tty_node.open().unwrap()).unwrap();
|
||||
io.place_file(tty_node.open(OpenFlags::O_RDWR).unwrap()).unwrap();
|
||||
}
|
||||
|
||||
drop(cfg);
|
||||
|
||||
@@ -161,6 +161,17 @@ impl ProcessIo {
|
||||
Err(Errno::TooManyDescriptors)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn close_file(&mut self, idx: usize) -> Result<(), Errno> {
|
||||
if self.file_bitmap & (1 << idx) == 0 {
|
||||
return Err(Errno::InvalidFile);
|
||||
}
|
||||
|
||||
let res = self.files.remove(&idx);
|
||||
assert!(res.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
+24
-12
@@ -5,10 +5,8 @@ use core::mem::size_of;
|
||||
use core::time::Duration;
|
||||
use error::Errno;
|
||||
use libcommon::{Read, Write};
|
||||
use syscall::{
|
||||
abi,
|
||||
stat::{Stat, AT_FDCWD},
|
||||
};
|
||||
use syscall::{abi, stat::AT_FDCWD};
|
||||
use vfs::{FileMode, OpenFlags, Stat};
|
||||
|
||||
fn translate(virt: usize) -> Option<usize> {
|
||||
let mut res: usize;
|
||||
@@ -24,9 +22,7 @@ fn translate(virt: usize) -> Option<usize> {
|
||||
|
||||
fn validate_user_ptr_struct<'a, T>(base: usize) -> Result<&'a mut T, Errno> {
|
||||
let bytes = validate_user_ptr(base, size_of::<T>())?;
|
||||
Ok(unsafe {
|
||||
&mut *(bytes.as_mut_ptr() as *mut T)
|
||||
})
|
||||
Ok(unsafe { &mut *(bytes.as_mut_ptr() as *mut T) })
|
||||
}
|
||||
|
||||
fn validate_user_ptr<'a>(base: usize, len: usize) -> Result<&'a mut [u8], Errno> {
|
||||
@@ -119,15 +115,23 @@ pub unsafe fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
}
|
||||
|
||||
// I/O system calls
|
||||
abi::SYS_OPEN => {
|
||||
let path = validate_user_str(args[0], 256)?;
|
||||
abi::SYS_OPENAT => {
|
||||
let at_fd = args[0];
|
||||
let path = validate_user_str(args[1], 256)?;
|
||||
let mode = FileMode::from_bits(args[2] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
let opts = OpenFlags::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
|
||||
let at = if at_fd as i32 == AT_FDCWD {
|
||||
None
|
||||
} else {
|
||||
todo!();
|
||||
};
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
let node = io.ioctx().find(None, path, true)?;
|
||||
// TODO check access
|
||||
io.place_file(node.open()?)
|
||||
let file = io.ioctx().open(at, path, mode, opts)?;
|
||||
io.place_file(file)
|
||||
}
|
||||
abi::SYS_READ => {
|
||||
let proc = Process::current();
|
||||
@@ -160,6 +164,14 @@ pub unsafe fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
node.stat(buf)?;
|
||||
Ok(0)
|
||||
}
|
||||
abi::SYS_CLOSE => {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
let fd = args[0];
|
||||
|
||||
io.close_file(fd)?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
// Extra system calls
|
||||
abi::SYS_EX_DEBUG_TRACE => {
|
||||
|
||||
Reference in New Issue
Block a user