From beb653305967b62210eb3fbf635587445b2fbc6f Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 8 Nov 2018 16:56:01 +0800 Subject: [PATCH] impl sys_getdirentry. 'ls' ok. --- kernel/Cargo.lock | 2 +- kernel/src/syscall.rs | 44 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index d715539..0e42a9c 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -209,7 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "simple-filesystem" version = "0.0.1" -source = "git+https://github.com/wangrunji0408/SimpleFileSystem-Rust?branch=multi-thread#fe473bc987a9a5dfd7ffe91883f8781b910ed45e" +source = "git+https://github.com/wangrunji0408/SimpleFileSystem-Rust?branch=multi-thread#978c3a70ca7bd3fdd536cc91b8d2f2f3b2dcb29b" dependencies = [ "bit-vec 0.5.0 (git+https://github.com/AltSysrq/bit-vec.git)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index d9f916c..1d79e66 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -1,7 +1,5 @@ //! System call -#![allow(unused)] - use arch::interrupt::TrapFrame; use process::*; use thread; @@ -24,7 +22,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &TrapFrame) -> i32 { 110 => sys_fstat(args[0], args[1] as *mut Stat), // 111 => sys_fsync(), // 121 => sys_getcwd(), -// 128 => sys_getdirentry(args[0], args[1]), + 128 => sys_getdirentry(args[0], args[1] as *mut DirEntry), 130 => sys_dup(args[0], args[1]), // process @@ -138,6 +136,26 @@ fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> i32 { 0 } +/// entry_id = dentry.offset / 256 +/// dentry.name = entry_name +/// dentry.offset += 256 +fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> i32 { + // TODO: check ptr + info!("getdirentry: {}", fd); + let file = process().files.get(&fd); + if file.is_none() { return -1; } + let file = file.unwrap(); + let dentry = unsafe { &mut *dentry_ptr }; + if !dentry.check() { return -1; } + let info = file.lock().info().unwrap(); + if info.type_ != FileType::Dir || info.size <= dentry.entry_id() { return -1; } + let name = file.lock().get_entry(dentry.entry_id()); + if name.is_err() { return -1; } + let name = name.unwrap(); + dentry.set_name(name.as_str()); + 0 +} + fn sys_dup(fd1: usize, fd2: usize) -> i32 { info!("dup: {} {}", fd1, fd2); let file = process().files.get(&fd1); @@ -271,6 +289,26 @@ impl VfsFlags { } } +#[repr(C)] +struct DirEntry { + offset: u32, + name: [u8; 256], +} + +impl DirEntry { + fn check(&self) -> bool { + self.offset % 256 == 0 + } + fn entry_id(&self) -> usize { + (self.offset / 256) as usize + } + fn set_name(&mut self, name: &str) { + self.name[..name.len()].copy_from_slice(name.as_bytes()); + self.name[name.len()] = 0; + self.offset += 256; + } +} + #[repr(C)] struct Stat { /// protection mode and file type