Skip to content

Commit

Permalink
fix: incompatible interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
PKTH-Jx committed Feb 19, 2025
1 parent 4a99179 commit 18bc4a9
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 522 deletions.
79 changes: 48 additions & 31 deletions api/ruxos_posix_api/src/imp/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@ use core::{
};

use axerrno::{LinuxError, LinuxResult};
use axio::{Error, PollState, SeekFrom};
use axsync::Mutex;
use capability::Cap;
use axio::{Error, SeekFrom};
use ruxfdtable::{FileLike, RuxStat};
use ruxfs::{
fops::{self, DirEntry},
fops::{self, DirEntry, OpenOptions},
AbsPath, RelPath,
};

use crate::{ctypes, utils::char_ptr_to_str};
use alloc::vec::Vec;
use crate::ctypes;
use ruxtask::fs::{get_file_like, Directory, File};

use super::stdio::{stdin, stdout};
Expand All @@ -42,13 +39,34 @@ impl ruxtask::fs::InitFs for InitFsImpl {
}
}

/// Convert open flags to [`Cap`].
fn flags_to_cap(flags: u32) -> Cap {
/// Convert open flags to [`OpenOptions`].
pub fn flags_to_options(flags: c_int, _mode: ctypes::mode_t) -> OpenOptions {
let flags = flags as u32;
let mut options = OpenOptions::new();
match flags & 0b11 {
ctypes::O_RDONLY => Cap::READ,
ctypes::O_WRONLY => Cap::WRITE,
_ => Cap::READ | Cap::WRITE,
ctypes::O_RDONLY => options.read(true),
ctypes::O_WRONLY => options.write(true),
_ => {
options.read(true);
options.write(true);
}
};
if flags & ctypes::O_APPEND != 0 {
options.append(true);
}
if flags & ctypes::O_TRUNC != 0 {
options.truncate(true);
}
if flags & ctypes::O_CREAT != 0 {
options.create(true);
}
if flags & ctypes::O_EXEC != 0 {
options.create_new(true);
}
if flags & ctypes::O_CLOEXEC != 0 {
options.cloexec(true);
}
options
}

/// Open a file by `filename` and insert it into the file descriptor table.
Expand All @@ -58,6 +76,7 @@ fn flags_to_cap(flags: u32) -> Cap {
pub fn sys_open(filename: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int {
syscall_body!(sys_open, {
let path = parse_path(filename)?;
let opts = flags_to_options(flags, mode);
let flags = flags as u32;
debug!("sys_open <= {:?} {:#o} {:#o}", path, flags, mode);
// Check flag and attr
Expand Down Expand Up @@ -85,18 +104,17 @@ pub fn sys_open(filename: *const c_char, flags: c_int, mode: ctypes::mode_t) ->
node.truncate(0)?;
}
// Open
let append = flags & ctypes::O_APPEND != 0;
let file = fops::open_file(&path, node, flags_to_cap(flags), append)?;
File::new(file).add_to_fd_table()
let file = fops::open_file(&path, node, &opts)?;
File::new(file).add_to_fd_table(opts)
})
}

/// Open a file under a specific dir
pub fn sys_openat(fd: c_int, path: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int {
syscall_body!(sys_openat, {
let path = parse_path_at(fd, path)?;
let opts = flags_to_options(flags, mode);
let flags = flags as u32;
let cap = flags_to_cap(flags);
debug!(
"sys_openat <= {}, {:?}, {:#o}, {:#o}",
fd, path, flags, mode
Expand Down Expand Up @@ -132,13 +150,12 @@ pub fn sys_openat(fd: c_int, path: *const c_char, flags: c_int, mode: ctypes::mo
Err(e) => return Err(e.into()),
};
// Open file or directory
let append = flags & ctypes::O_APPEND != 0;
if node.get_attr()?.is_dir() {
let dir = fops::open_dir(&path, node, cap)?;
Directory::new(dir, flags & ctypes::O_SEARCH != 0).add_to_fd_table()
let dir = fops::open_dir(&path, node, &opts)?;
Directory::new(dir, flags & ctypes::O_SEARCH != 0).add_to_fd_table(opts)
} else {
let file = fops::open_file(&path, node, cap, append)?;
File::new(file).add_to_fd_table()
let file = fops::open_file(&path, node, &opts)?;
File::new(file).add_to_fd_table(opts)
}
})
}
Expand Down Expand Up @@ -228,11 +245,11 @@ pub unsafe fn sys_stat(path: *const c_char, buf: *mut core::ffi::c_void) -> c_in
}
let node = fops::lookup(&path)?;
let attr = node.get_attr()?;
let st = if attr.is_dir() {
let dir = fops::open_dir(&path, node, Cap::empty())?;
let st: RuxStat = if attr.is_dir() {
let dir = fops::open_dir(&path, node, &OpenOptions::new())?;
Directory::new(dir, false).stat()?.into()
} else {
let file = fops::open_file(&path, node, Cap::empty(), false)?;
let file = fops::open_file(&path, node, &OpenOptions::new())?;
File::new(file).stat()?.into()
};

Expand Down Expand Up @@ -335,9 +352,9 @@ pub unsafe fn sys_newfstatat(
}
let node = fops::lookup(&path)?;
let st = if node.get_attr()?.is_dir() {
Directory::new(fops::open_dir(&path, node, Cap::empty())?, false).stat()?
Directory::new(fops::open_dir(&path, node, &OpenOptions::new())?, false).stat()?
} else {
File::new(fops::open_file(&path, node, Cap::empty(), false)?).stat()?
File::new(fops::open_file(&path, node, &OpenOptions::new())?).stat()?
};
unsafe {
(*kst).st_dev = st.st_dev;
Expand All @@ -362,7 +379,7 @@ pub fn sys_getcwd(buf: *mut c_char, size: usize) -> c_int {
return Err(LinuxError::EINVAL);
}
let dst = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, size as _) };
let cwd = fops::current_dir();
let cwd = fops::current_dir()?;
let cwd = cwd.as_bytes();
if cwd.len() < size {
dst[..cwd.len()].copy_from_slice(cwd);
Expand Down Expand Up @@ -591,8 +608,8 @@ pub unsafe fn sys_getdents64(fd: c_int, dirp: *mut LinuxDirent64, count: ctypes:

loop {
let mut entry = [DirEntry::default()];
let offset = dir.inner.lock().entry_idx();
let n = dir.inner.lock().read_dir(&mut entry)?;
let offset = dir.inner.read().entry_idx();
let n = dir.inner.write().read_dir(&mut entry)?;
debug!(
"entry {:?}",
str::from_utf8(entry[0].name_as_bytes()).unwrap()
Expand All @@ -610,7 +627,7 @@ pub unsafe fn sys_getdents64(fd: c_int, dirp: *mut LinuxDirent64, count: ctypes:
if written + entry_size > count {
debug!("buf not big enough");
// revert the offset
dir.inner.lock().set_entry_idx(offset);
dir.inner.write().set_entry_idx(offset);
break;
}

Expand Down Expand Up @@ -709,7 +726,7 @@ pub fn parse_path(path: *const c_char) -> LinuxResult<AbsPath<'static>> {
if path.starts_with('/') {
Ok(AbsPath::new_canonicalized(path))
} else {
Ok(fops::current_dir().join(&RelPath::new_canonicalized(path)))
Ok(fops::current_dir()?.join(&RelPath::new_canonicalized(path)))
}
}

Expand All @@ -725,7 +742,7 @@ pub fn parse_path_at(dirfd: c_int, path: *const c_char) -> LinuxResult<AbsPath<'
if path.starts_with('/') {
Ok(AbsPath::new_canonicalized(path))
} else if dirfd == ctypes::AT_FDCWD {
Ok(fops::current_dir().join(&RelPath::new_canonicalized(path)))
Ok(fops::current_dir()?.join(&RelPath::new_canonicalized(path)))
} else {
let dir = Directory::from_fd(dirfd)?;
if dir.searchable {
Expand Down
2 changes: 0 additions & 2 deletions modules/ruxfdtable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ use core::marker::Sync;
use axerrno::LinuxResult;
use axfs_vfs::AbsPath;
use axio::PollState;
use flatten_objects::FlattenObjects;
use spin::RwLock;

#[derive(Default)]
///Rust version for struct timespec in ctypes. Represents a high-resolution time specification.
Expand Down
1 change: 0 additions & 1 deletion modules/ruxfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ axfs_vfs = { path = "../../crates/axfs_vfs" }
axfs_devfs = { path = "../../crates/axfs_devfs", optional = true }
axfs_ramfs = { path = "../../crates/axfs_ramfs", optional = true }
crate_interface = { version = "0.1.1" }
memory_addr = "0.1.0"

ruxdriver = { path = "../ruxdriver", features = ["block"] }
axalloc = { path = "../axalloc", optional = true }
Expand Down
3 changes: 1 addition & 2 deletions modules/ruxfs/src/api/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use alloc::{borrow::ToOwned, string::String, vec};
use axerrno::ax_err;
use axfs_vfs::{AbsPath, VfsError};
use axio::Result;
use capability::Cap;
use core::{fmt, str};

use super::FileType;
Expand All @@ -26,7 +25,7 @@ impl Directory {
/// Opens a directory for reading entries.
pub fn open(path: AbsPath<'static>) -> Result<Self> {
let node = fops::lookup(&path)?;
let inner = fops::open_dir(&path, node, Cap::EXECUTE)?;
let inner = fops::open_dir(&path, node, &fops::OpenOptions::new())?;
Ok(Self { inner })
}

Expand Down
85 changes: 14 additions & 71 deletions modules/ruxfs/src/api/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use axerrno::ax_err;
use axfs_vfs::{AbsPath, VfsError};
use axio::{prelude::*, Result, SeekFrom};
use capability::Cap;
use core::fmt;

use crate::fops;
Expand All @@ -27,109 +26,66 @@ pub type FileAttr = fops::FileAttr;

/// Options and flags which can be used to configure how a file is opened.
#[derive(Clone)]
pub struct OpenOptions {
// generic
read: bool,
write: bool,
append: bool,
truncate: bool,
create: bool,
create_new: bool,
// system-specific
_custom_flags: i32,
_mode: u32,
}
pub struct OpenOptions(fops::OpenOptions);

impl OpenOptions {
/// Creates a blank new set of options ready for configuration.
pub const fn new() -> Self {
Self {
// generic
read: false,
write: false,
append: false,
truncate: false,
create: false,
create_new: false,
// system-specific
_custom_flags: 0,
_mode: 0o666,
}
Self(fops::OpenOptions::new())
}

/// Sets the option for read access.
pub fn read(&mut self, read: bool) -> &mut Self {
self.read = read;
self.0.read(read);
self
}

/// Sets the option for write access.
pub fn write(&mut self, write: bool) -> &mut Self {
self.write = write;
self.0.write(write);
self
}

/// Sets the option for the append mode.
pub fn append(&mut self, append: bool) -> &mut Self {
self.append = append;
self.0.append(append);
self
}

/// Sets the option for truncating a previous file.
pub fn truncate(&mut self, truncate: bool) -> &mut Self {
self.truncate = truncate;
self.0.truncate(truncate);
self
}

/// Sets the option to create a new file, or open it if it already exists.
pub fn create(&mut self, create: bool) -> &mut Self {
self.create = create;
self.0.create(create);
self
}

/// Sets the option to create a new file, failing if it already exists.
pub fn create_new(&mut self, create_new: bool) -> &mut Self {
self.create_new = create_new;
self.0.create_new(create_new);
self
}

/// Check if the options are valid.
pub const fn is_valid(&self) -> bool {
if !self.read && !self.write && !self.append {
return false;
}
match (self.write, self.append) {
(true, false) => {}
(false, false) => {
if self.truncate || self.create || self.create_new {
return false;
}
}
(_, true) => {
if self.truncate && !self.create_new {
return false;
}
}
}
true
}

/// Opens a file at `path` with the options specified by `self`.
pub fn open(&self, path: &AbsPath) -> Result<File> {
// Check options
if !self.is_valid() {
if !self.0.is_valid() {
return ax_err!(InvalidInput);
}
// Find node, check flag and attr
let node = match fops::lookup(&path) {
Ok(node) => {
if self.create_new {
if self.0.create_new {
return ax_err!(AlreadyExists);
}
node
}
Err(VfsError::NotFound) => {
if !self.create && !self.create_new {
if !self.0.create && !self.0.create_new {
return ax_err!(NotFound);
}
fops::create_file(&path)?;
Expand All @@ -141,11 +97,11 @@ impl OpenOptions {
return ax_err!(IsADirectory);
}
// Truncate
if self.truncate {
if self.0.truncate {
node.truncate(0)?;
}
// Open
fops::open_file(&path, node, self.into(), self.append).map(|inner| File { inner })
fops::open_file(&path, node, &self.0).map(|inner| File { inner })
}
}

Expand Down Expand Up @@ -227,26 +183,13 @@ impl Seek for File {
}
}

impl From<&OpenOptions> for Cap {
fn from(opts: &OpenOptions) -> Cap {
let mut cap = Cap::empty();
if opts.read {
cap |= Cap::READ;
}
if opts.write | opts.append {
cap |= Cap::WRITE;
}
cap
}
}

impl fmt::Debug for OpenOptions {
#[allow(unused_assignments)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut written = false;
macro_rules! fmt_opt {
($field: ident, $label: literal) => {
if self.$field {
if self.0.$field {
if written {
write!(f, " | ")?;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/ruxfs/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub use file::{File, FileAttr, FilePerm, FileType, OpenOptions};

/// Returns the current working directory as a [`AbsPath`].
pub fn current_dir() -> io::Result<AbsPath<'static>> {
Ok(fops::current_dir())
Ok(fops::current_dir().unwrap())
}

/// Changes the current working directory to the specified path.
Expand Down
Loading

0 comments on commit 18bc4a9

Please sign in to comment.