mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2025-12-23 22:47:55 -05:00
implement sys_fchdir
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
| 0x2f (47) | fallocate | (int fd, int mode, loff_t offset, loff_t len) | __arm64_sys_fallocate | false |
|
||||
| 0x30 (48) | faccessat | (int dfd, const char *filename, int mode) | __arm64_sys_faccessat | true |
|
||||
| 0x31 (49) | chdir | (const char *filename) | __arm64_sys_chdir | true |
|
||||
| 0x32 (50) | fchdir | (unsigned int fd) | __arm64_sys_fchdir | false |
|
||||
| 0x32 (50) | fchdir | (unsigned int fd) | __arm64_sys_fchdir | true |
|
||||
| 0x33 (51) | chroot | (const char *filename) | __arm64_sys_chroot | true |
|
||||
| 0x34 (52) | fchmod | (unsigned int fd, umode_t mode) | __arm64_sys_fchmod | false |
|
||||
| 0x35 (53) | fchmodat | (int dfd, const char *filename, umode_t mode) | __arm64_sys_fchmodat | false |
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! This module provides a `Path` struct that is a thin wrapper around `&str`,
|
||||
//! offering various methods for path inspection and manipulation.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{borrow::ToOwned, vec::Vec};
|
||||
|
||||
use super::pathbuf::PathBuf;
|
||||
|
||||
@@ -217,6 +217,14 @@ impl AsRef<Path> for str {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOwned for Path {
|
||||
type Owned = PathBuf;
|
||||
|
||||
fn to_owned(&self) -> Self::Owned {
|
||||
PathBuf::from(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the components of a `Path`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Components<'a> {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use super::path::Path;
|
||||
use alloc::string::String;
|
||||
use core::ops::Deref;
|
||||
use core::{borrow::Borrow, ops::Deref};
|
||||
|
||||
/// An owned, mutable path, akin to `String`.
|
||||
///
|
||||
@@ -164,6 +164,12 @@ impl Deref for PathBuf {
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<Path> for PathBuf {
|
||||
fn borrow(&self) -> &Path {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PathBuf;
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
use crate::fs::syscalls::chdir::sys_chroot;
|
||||
use crate::fs::syscalls::trunc::sys_ftruncate;
|
||||
use crate::kernel::power::sys_reboot;
|
||||
use crate::kernel::rand::sys_getrandom;
|
||||
use crate::memory::mmap::sys_mprotect;
|
||||
use crate::{
|
||||
arch::{Arch, ArchImpl},
|
||||
clock::{gettime::sys_clock_gettime, timeofday::sys_gettimeofday},
|
||||
@@ -18,7 +13,7 @@ use crate::{
|
||||
stat::sys_newfstatat,
|
||||
unlink::sys_unlinkat,
|
||||
},
|
||||
chdir::{sys_chdir, sys_getcwd},
|
||||
chdir::{sys_chdir, sys_chroot, sys_fchdir, sys_getcwd},
|
||||
close::sys_close,
|
||||
ioctl::sys_ioctl,
|
||||
iov::{sys_readv, sys_writev},
|
||||
@@ -27,13 +22,13 @@ use crate::{
|
||||
splice::sys_sendfile,
|
||||
stat::sys_fstat,
|
||||
sync::sys_sync,
|
||||
trunc::sys_ftruncate,
|
||||
},
|
||||
},
|
||||
kernel::sysinfo::sys_sysinfo,
|
||||
kernel::uname::sys_uname,
|
||||
kernel::{power::sys_reboot, rand::sys_getrandom, sysinfo::sys_sysinfo, uname::sys_uname},
|
||||
memory::{
|
||||
brk::sys_brk,
|
||||
mmap::{sys_mmap, sys_munmap},
|
||||
mmap::{sys_mmap, sys_mprotect, sys_munmap},
|
||||
},
|
||||
process::{
|
||||
clone::sys_clone,
|
||||
@@ -101,6 +96,7 @@ pub async fn handle_syscall() {
|
||||
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,
|
||||
0x30 => sys_faccessat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
||||
0x31 => sys_chdir(TUA::from_value(arg1 as _)).await,
|
||||
0x32 => sys_fchdir(arg1.into()).await,
|
||||
0x33 => sys_chroot(TUA::from_value(arg1 as _)).await,
|
||||
0x38 => {
|
||||
sys_openat(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::{collections::btree_map::BTreeMap, sync::Arc};
|
||||
use async_trait::async_trait;
|
||||
@@ -337,14 +338,14 @@ impl VFS {
|
||||
FileType::File => {
|
||||
let mut open_file =
|
||||
OpenFile::new(Box::new(RegFile::new(target_inode.clone())), flags);
|
||||
open_file.set_inode(target_inode);
|
||||
open_file.update(target_inode, path.to_owned());
|
||||
|
||||
Ok(Arc::new(open_file))
|
||||
}
|
||||
FileType::Directory => {
|
||||
let mut open_file =
|
||||
OpenFile::new(Box::new(DirFile::new(target_inode.clone())), flags);
|
||||
open_file.set_inode(target_inode);
|
||||
open_file.update(target_inode, path.to_owned());
|
||||
|
||||
Ok(Arc::new(open_file))
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
use core::{future, pin::Pin, task::Poll};
|
||||
use libkernel::{
|
||||
error::Result,
|
||||
fs::{Inode, OpenFlags},
|
||||
fs::{Inode, OpenFlags, path::Path, pathbuf::PathBuf},
|
||||
};
|
||||
|
||||
pub struct FileCtx {
|
||||
@@ -23,6 +23,7 @@ impl FileCtx {
|
||||
|
||||
pub struct OpenFile {
|
||||
inode: Option<Arc<dyn Inode>>,
|
||||
path: Option<PathBuf>,
|
||||
state: Mutex<(Box<dyn FileOps>, FileCtx)>,
|
||||
}
|
||||
|
||||
@@ -31,17 +32,23 @@ impl OpenFile {
|
||||
Self {
|
||||
state: Mutex::new((ops, FileCtx::new(flags))),
|
||||
inode: None,
|
||||
path: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_inode(&mut self, inode: Arc<dyn Inode>) {
|
||||
self.inode = Some(inode)
|
||||
pub fn update(&mut self, inode: Arc<dyn Inode>, path: PathBuf) {
|
||||
self.inode = Some(inode);
|
||||
self.path = Some(path);
|
||||
}
|
||||
|
||||
pub fn inode(&self) -> Option<Arc<dyn Inode>> {
|
||||
self.inode.clone()
|
||||
}
|
||||
|
||||
pub fn path(&self) -> Option<&Path> {
|
||||
self.path.as_deref()
|
||||
}
|
||||
|
||||
pub async fn flags(&self) -> OpenFlags {
|
||||
self.state.lock().await.1.flags
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::{
|
||||
fs::VFS,
|
||||
memory::uaccess::{copy_to_user_slice, cstr::UserCStr},
|
||||
process::fd_table::Fd,
|
||||
sched::current_task,
|
||||
};
|
||||
use alloc::{ffi::CString, string::ToString};
|
||||
use alloc::{borrow::ToOwned, ffi::CString, string::ToString};
|
||||
use core::{ffi::c_char, str::FromStr};
|
||||
use libkernel::{
|
||||
error::{KernelError, Result},
|
||||
@@ -55,3 +56,19 @@ pub async fn sys_chroot(path: TUA<c_char>) -> Result<usize> {
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub async fn sys_fchdir(fd: Fd) -> Result<usize> {
|
||||
let task = current_task();
|
||||
let file = task
|
||||
.fd_table
|
||||
.lock_save_irq()
|
||||
.get(fd)
|
||||
.ok_or(KernelError::BadFd)?;
|
||||
|
||||
*task.cwd.lock_save_irq() = (
|
||||
file.inode().ok_or(KernelError::BadFd)?,
|
||||
file.path().ok_or(KernelError::BadFd)?.to_owned(),
|
||||
);
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
@@ -47,11 +47,51 @@ fn test_readdir() {
|
||||
|
||||
fn test_chdir() {
|
||||
print!("Testing chdir syscall ...");
|
||||
let path = std::ffi::CString::new("/").unwrap();
|
||||
let path = std::ffi::CString::new("/dev").unwrap();
|
||||
let mut buffer = [1u8; 16];
|
||||
unsafe {
|
||||
if libc::chdir(path.as_ptr()) != 0 {
|
||||
panic!("chdir failed");
|
||||
}
|
||||
if libc::getcwd(
|
||||
buffer.as_mut_ptr() as *mut libc::c_char,
|
||||
buffer.len() as libc::size_t,
|
||||
)
|
||||
.is_null()
|
||||
{
|
||||
panic!("getcwd failed");
|
||||
}
|
||||
if std::ffi::CStr::from_ptr(buffer.as_ptr()).to_string_lossy() != "/dev" {
|
||||
panic!("chdir failed");
|
||||
}
|
||||
}
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn test_fchdir() {
|
||||
print!("Testing fchdir syscall ...");
|
||||
let path = std::ffi::CString::new("/dev").unwrap();
|
||||
let mut buffer = [1u8; 16];
|
||||
unsafe {
|
||||
let fd = libc::open(path.as_ptr(), libc::O_RDONLY);
|
||||
if fd == -1 {
|
||||
panic!("open failed");
|
||||
}
|
||||
if libc::fchdir(fd) != 0 {
|
||||
panic!("fchdir failed");
|
||||
}
|
||||
if libc::getcwd(
|
||||
buffer.as_mut_ptr() as *mut libc::c_char,
|
||||
buffer.len() as libc::size_t,
|
||||
)
|
||||
.is_null()
|
||||
{
|
||||
panic!("getcwd failed");
|
||||
}
|
||||
if std::ffi::CStr::from_ptr(buffer.as_ptr()).to_string_lossy() != "/dev" {
|
||||
panic!("fchdir failed");
|
||||
}
|
||||
libc::close(fd);
|
||||
}
|
||||
println!(" OK");
|
||||
}
|
||||
@@ -240,6 +280,7 @@ fn main() {
|
||||
run_test(test_opendir);
|
||||
run_test(test_readdir);
|
||||
run_test(test_chdir);
|
||||
run_test(test_fchdir);
|
||||
run_test(test_chroot);
|
||||
run_test(test_fork);
|
||||
run_test(test_read);
|
||||
|
||||
Reference in New Issue
Block a user