Adding openat syscall

This commit is contained in:
Darley Barreto
2025-07-13 12:43:20 +00:00
committed by Jeremy Soller
parent caf5fa955b
commit 66ea2b46ee
5 changed files with 176 additions and 13 deletions
+72 -12
View File
@@ -1,7 +1,7 @@
//! Filesystem syscalls
use core::num::NonZeroUsize;
use alloc::{sync::Arc, vec::Vec};
use alloc::{string::String, sync::Arc, vec::Vec};
use redox_path::RedoxPath;
use spin::RwLock;
@@ -12,7 +12,7 @@ use crate::{
memory::{AddrSpace, GenericFlusher, Grant, PageSpan, TlbShootdownActions},
},
paging::{Page, VirtualAddress, PAGE_SIZE},
scheme::{self, CallerCtx, FileHandle, KernelScheme, OpenResult},
scheme::{self, CallerCtx, FileHandle, KernelScheme, OpenResult, StrOrBytes},
syscall::{data::Stat, error::*, flag::*},
};
@@ -41,19 +41,28 @@ pub fn file_op_generic_ext<T>(
op(&*scheme, file.description, desc)
}
pub fn copy_path_to_buf(raw_path: UserSliceRo, max_len: usize) -> Result<alloc::string::String> {
pub fn copy_path_to_buf(raw_path: UserSliceRo, max_len: usize) -> Result<String> {
let mut path_buf = vec![0_u8; max_len];
if raw_path.len() > path_buf.len() {
return Err(Error::new(ENAMETOOLONG));
}
let path_len = raw_path.copy_common_bytes_to_slice(&mut path_buf)?;
path_buf.truncate(path_len);
alloc::string::String::from_utf8(path_buf).map_err(|_| Error::new(EINVAL))
String::from_utf8(path_buf).map_err(|_| Error::new(EINVAL))
//core::str::from_utf8(&path_buf[..path_len]).map_err(|_| Error::new(EINVAL))
}
// TODO: Define elsewhere
const PATH_MAX: usize = PAGE_SIZE;
#[inline]
fn is_legacy(path_buf: &String) -> bool {
// FIXME remove entries from this list as the respective programs get updated
path_buf.starts_with(':')
|| path_buf == "null:" // FIXME Remove exception at next rustc update (rust#138457)
|| path_buf == "sys:exe" // FIXME Remove exception at next rustc update (rust#138457)
|| path_buf.starts_with("orbital:")
}
/// Open syscall
pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
let (pid, uid, gid, scheme_ns) = match context::current().read() {
@@ -70,12 +79,7 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
// Display a deprecation warning for any usage of the legacy scheme syntax (scheme:/path)
// FIXME remove entries from this list as the respective programs get updated
if path_buf.contains(':')
&& !path_buf.starts_with(':')
&& path_buf != "null:" // FIXME Remove exception at next rustc update (rust#138457)
&& path_buf != "sys:exe" // FIXME Remove exception at next rustc update (rust#138457)
&& !path_buf.starts_with("orbital:")
{
if path_buf.contains(':') && !is_legacy(&path_buf) {
let name = context::current().read().name.clone();
if name.contains("cosmic") && (path_buf == "event:" || path_buf.starts_with("time:")) {
// FIXME cosmic apps likely need crate updates
@@ -83,7 +87,6 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
println!("deprecated: legacy path {:?} used by {}", path_buf, name);
}
}
let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?;
let (scheme_name, reference) = path.as_parts().ok_or(Error::new(EINVAL))?;
@@ -110,7 +113,6 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
}
};
//drop(path_buf);
context::current()
.read()
.add_file(FileDescriptor {
@@ -120,6 +122,64 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
.ok_or(Error::new(EMFILE))
}
pub fn openat(
fh: FileHandle,
raw_path: UserSliceRo,
flags: usize,
fcntl_flags: u32,
) -> Result<FileHandle> {
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
if is_legacy(&path_buf) {
// TODO: implement
return Err(Error::new(EINVAL));
}
let pipe = context::current()
.read()
.get_file(fh)
.ok_or(Error::new(EBADF))?;
let description = pipe.description.read();
let caller_ctx = context::current().read().caller_ctx();
let new_description = {
let scheme = scheme::schemes()
.get(description.scheme)
.ok_or(Error::new(EBADF))?
.clone();
let res = scheme.kopenat(
description.number,
StrOrBytes::from_str(&path_buf),
flags,
fcntl_flags,
caller_ctx,
);
match res? {
OpenResult::SchemeLocal(number, internal_flags) => {
Arc::new(RwLock::new(FileDescription {
offset: 0,
internal_flags,
scheme: description.scheme,
number,
flags: description.flags,
}))
}
OpenResult::External(desc) => desc,
}
};
context::current()
.read()
.add_file(FileDescriptor {
description: new_description,
cloexec: false,
})
.ok_or(Error::new(EMFILE))
}
/// rmdir syscall
pub fn rmdir(raw_path: UserSliceRo) -> Result<()> {
let (scheme_ns, caller_ctx) = match context::current().read() {
+1
View File
@@ -178,6 +178,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> us
),
SYS_OPEN => open(UserSlice::ro(b, c)?, d).map(FileHandle::into),
SYS_OPENAT => openat(fd, UserSlice::ro(c, d)?, e, f as _).map(FileHandle::into),
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?).map(|()| 0),
SYS_UNLINK => unlink(UserSlice::ro(b, c)?).map(|()| 0),
SYS_YIELD => sched_yield().map(|()| 0),