Adding openat syscall
This commit is contained in:
committed by
Jeremy Soller
parent
caf5fa955b
commit
66ea2b46ee
+72
-12
@@ -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() {
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user