From e0b928f7c573dbf67c26e91743266f35365a0016 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 08:16:39 -0700 Subject: [PATCH 1/8] add flock and sysinfo --- linux-syscall/src/file/fd.rs | 19 ++++++++++++++++++ linux-syscall/src/lib.rs | 4 ++-- linux-syscall/src/misc.rs | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/linux-syscall/src/file/fd.rs b/linux-syscall/src/file/fd.rs index 48458811f..c64c7d4eb 100644 --- a/linux-syscall/src/file/fd.rs +++ b/linux-syscall/src/file/fd.rs @@ -111,6 +111,25 @@ impl Syscall<'_> { Ok(0) } + + /// apply or remove an advisory lock on an open file + /// TODO: handle operation + pub fn sys_flock(&mut self, fd: FileDesc, operation: usize) -> SysResult { + bitflags! { + struct Operation: u8 { + const LOCK_SH = 1; + const LOCK_EX = 2; + const LOCK_NB = 4; + const LOCK_UN = 8; + } + } + let operation = Operation::from_bits(operation as u8).unwrap(); + info!("flock: fd: {:?}, operation: {:?}", fd, operation); + let proc = self.linux_process(); + + proc.get_file(fd)?; + Ok(0) + } } bitflags! { diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index a5d0dff46..ed1a2ee0d 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -92,7 +92,7 @@ impl Syscall<'_> { Sys::WRITEV => self.sys_writev(a0.into(), a1.into(), a2), Sys::SENDFILE => self.sys_sendfile(a0.into(), a1.into(), a2.into(), a3), Sys::FCNTL => self.sys_fcntl(a0.into(), a1, a2), - Sys::FLOCK => self.unimplemented("flock", Ok(0)), + Sys::FLOCK => self.sys_flock(a0.into(), a1.into()), Sys::FSYNC => self.sys_fsync(a0.into()), Sys::FDATASYNC => self.sys_fdatasync(a0.into()), Sys::TRUNCATE => self.sys_truncate(a0.into(), a1), @@ -200,7 +200,7 @@ impl Syscall<'_> { // Sys::GETRLIMIT => self.sys_getrlimit(), // Sys::SETRLIMIT => self.sys_setrlimit(), Sys::GETRUSAGE => self.sys_getrusage(a0, a1.into()), - // Sys::SYSINFO => self.sys_sysinfo(a0.into()), + Sys::SYSINFO => self.sys_sysinfo(a0.into()), Sys::TIMES => self.sys_times(a0.into()), Sys::GETUID => self.unimplemented("getuid", Ok(0)), Sys::GETGID => self.unimplemented("getgid", Ok(0)), diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index 72c121ccc..488e9d868 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -30,6 +30,13 @@ impl Syscall<'_> { Ok(0) } + /// provides a simple way of getting overall system statistics + pub fn sys_sysinfo(&mut self, mut sys_info: UserOutPtr) -> SysResult { + let sysinfo = SysInfo::default(); + sys_info.write(sysinfo)?; + Ok(0) + } + /// provides a method for waiting until a certain condition becomes true. /// - `uaddr` - points to the futex word. /// - `op` - the operation to perform on the futex @@ -155,3 +162,33 @@ pub struct RLimit { cur: u64, // soft limit max: u64, // hard limit } + +/// sysinfo() return information sturct +#[repr(C)] +#[derive(Debug, Default)] +pub struct SysInfo { + /// Seconds since boot + uptime: u64, + /// 1, 5, and 15 minute load averages + loads: [u64; 3], + /// Total usable main memory size + totalram: u64, + /// Available memory size + freeram: u64, + /// Amount of shared memory + sharedram: u64, + /// Memory used by buffers + bufferram: u64, + /// Total swa Total swap space sizep space size + totalswap: u64, + /// swap space still available + freeswap: u64, + /// Number of current processes + procs: u16, + /// Total high memory size + totalhigh: u64, + /// Available high memory size + freehigh: u64, + /// Memory unit size in bytes + mem_unit: u32, +} From f64fea7890a81067f548cc171f5cc4402964c375 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 08:30:04 -0700 Subject: [PATCH 2/8] init document and some test --- linux-loader/src/main.rs | 8 +++++++- linux-object/src/error.rs | 1 + linux-object/src/fs/mod.rs | 1 + linux-object/src/loader/abi.rs | 1 + linux-object/src/loader/mod.rs | 1 + 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index 0d2eb36a4..f2f7f0280 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -84,8 +84,9 @@ mod tests { } #[async_std::test] - async fn test_date() { + async fn test_date_time() { assert_eq!(test("/bin/busybox date").await, 0); + assert_eq!(test("/bin/busybox uptime").await, 0); } #[async_std::test] @@ -148,6 +149,11 @@ mod tests { assert_eq!(test("/bin/busybox env").await, 0); } + #[async_std::test] + async fn test_ps() { + assert_eq!(test("/bin/busybox ps").await, 0); + } + // syscall unit test #[async_std::test] diff --git a/linux-object/src/error.rs b/linux-object/src/error.rs index d262f52af..316256a48 100644 --- a/linux-object/src/error.rs +++ b/linux-object/src/error.rs @@ -1,3 +1,4 @@ +//! Linux error flags use core::fmt; use rcore_fs::vfs::FsError; use zircon_object::ZxError; diff --git a/linux-object/src/fs/mod.rs b/linux-object/src/fs/mod.rs index c9f89fb39..f9d4d8b54 100644 --- a/linux-object/src/fs/mod.rs +++ b/linux-object/src/fs/mod.rs @@ -1,3 +1,4 @@ +//! Linux file objects use alloc::{boxed::Box, sync::Arc, vec::Vec}; use rcore_fs::vfs::*; diff --git a/linux-object/src/loader/abi.rs b/linux-object/src/loader/abi.rs index e2785331f..bf76525b6 100644 --- a/linux-object/src/loader/abi.rs +++ b/linux-object/src/loader/abi.rs @@ -1,3 +1,4 @@ +//! Process init info #![allow(unsafe_code)] use alloc::collections::btree_map::BTreeMap; diff --git a/linux-object/src/loader/mod.rs b/linux-object/src/loader/mod.rs index 37915975a..89ddfca84 100644 --- a/linux-object/src/loader/mod.rs +++ b/linux-object/src/loader/mod.rs @@ -1,3 +1,4 @@ +//! Linux ELF Program Loader use { crate::error::LxResult, crate::fs::INodeExt, From b97de4b7cdb474937dcbd7c3ca51de6924f741c5 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 19:50:27 -0700 Subject: [PATCH 3/8] fix clippy and add some test --- linux-loader/src/main.rs | 16 ++++++++++++++++ linux-syscall/src/lib.rs | 2 +- linux-syscall/test/testrandom.c | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 linux-syscall/test/testrandom.c diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index f2f7f0280..305399622 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -154,6 +154,17 @@ mod tests { assert_eq!(test("/bin/busybox ps").await, 0); } + #[async_std::test] + async fn test_sleep() { + assert_eq!(test("/bin/busybox sleep 3s").await, 0); + } + + #[async_std::test] + async fn test_truncate() { + assert_eq!(test("/bin/busybox truncate -s 12 testtruncate").await, 0); + fs::read("../rootfs/testtruncate").unwrap(); + } + // syscall unit test #[async_std::test] @@ -165,4 +176,9 @@ mod tests { async fn test_time() { assert_eq!(test("/bin/testtime").await, 0); } + + #[async_std::test] + async fn test_random() { + assert_eq!(test("/bin/testrandom").await, 0); + } } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index ed1a2ee0d..02a1d67bc 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -92,7 +92,7 @@ impl Syscall<'_> { Sys::WRITEV => self.sys_writev(a0.into(), a1.into(), a2), Sys::SENDFILE => self.sys_sendfile(a0.into(), a1.into(), a2.into(), a3), Sys::FCNTL => self.sys_fcntl(a0.into(), a1, a2), - Sys::FLOCK => self.sys_flock(a0.into(), a1.into()), + Sys::FLOCK => self.sys_flock(a0.into(), a1), Sys::FSYNC => self.sys_fsync(a0.into()), Sys::FDATASYNC => self.sys_fdatasync(a0.into()), Sys::TRUNCATE => self.sys_truncate(a0.into(), a1), diff --git a/linux-syscall/test/testrandom.c b/linux-syscall/test/testrandom.c new file mode 100644 index 000000000..bd504ba6e --- /dev/null +++ b/linux-syscall/test/testrandom.c @@ -0,0 +1,9 @@ + #include + #include + + int main(){ + int buf; + getrandom((void *)&buf,sizeof(buf),GRND_RANDOM); + printf("random: %d\n",buf); + return 0; + } \ No newline at end of file From f6672e32d6638d301f1229004860117facabb762 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 21:36:31 -0700 Subject: [PATCH 4/8] add unimplemented for schedule update info log in execve --- linux-object/src/fs/mod.rs | 12 ++++++++++++ linux-syscall/src/file/poll.rs | 6 +++--- linux-syscall/src/lib.rs | 4 ++-- linux-syscall/src/task.rs | 8 ++++---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/linux-object/src/fs/mod.rs b/linux-object/src/fs/mod.rs index f9d4d8b54..dbd479779 100644 --- a/linux-object/src/fs/mod.rs +++ b/linux-object/src/fs/mod.rs @@ -1,4 +1,5 @@ //! Linux file objects +//#![deny(missing_docs)] use alloc::{boxed::Box, sync::Arc, vec::Vec}; use rcore_fs::vfs::*; @@ -38,18 +39,27 @@ mod stdio; /// - Socket /// - Epoll instance pub trait FileLike: KernelObject { + /// read to buffer fn read(&self, buf: &mut [u8]) -> LxResult; + /// write from buffer fn write(&self, buf: &[u8]) -> LxResult; + /// read to buffer at given offset fn read_at(&self, offset: u64, buf: &mut [u8]) -> LxResult; + /// write from buffer at given offset fn write_at(&self, offset: u64, buf: &[u8]) -> LxResult; + /// wait for some event on a file descriptor fn poll(&self) -> LxResult; + /// wait for some event on a file descriptor use async async fn async_poll(&self) -> LxResult; + /// manipulates the underlying device parameters of special files fn ioctl(&self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> LxResult; + /// manipulate file descriptor fn fcntl(&self, cmd: usize, arg: usize) -> LxResult; } impl_downcast!(sync FileLike); +/// file descriptor wrapper #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] pub struct FileDesc(i32); @@ -90,6 +100,7 @@ impl Into for FileDesc { } } +/// create root filesystem, mount DevFS and RamFS pub fn create_root_fs(rootfs: Arc) -> Arc { let rootfs = MountFS::new(rootfs); let root = rootfs.root_inode(); @@ -127,6 +138,7 @@ pub fn create_root_fs(rootfs: Arc) -> Arc { root } +/// ext pub trait INodeExt { fn read_as_vec(&self) -> Result>; } diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index 539919a41..5a149d861 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -20,11 +20,11 @@ impl Syscall<'_> { nfds: usize, timeout_msecs: usize, ) -> SysResult { + let polls = ufds.read_array(nfds)?; info!( - "poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", - ufds, nfds, timeout_msecs + "poll: ufds: {:?}, nfds: {:?}, timeout_msecs: {:#x}", + polls, nfds, timeout_msecs ); - let polls = ufds.read_array(nfds)?; #[must_use = "future does nothing unless polled/`await`-ed"] struct PollFuture<'a> { polls: Vec, diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 02a1d67bc..8f623ff5c 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -148,8 +148,8 @@ impl Syscall<'_> { // Sys::KILL => self.sys_kill(a0, a1), // schedule - // Sys::SCHED_YIELD => self.sys_yield(), - // Sys::SCHED_GETAFFINITY => self.sys_sched_getaffinity(a0, a1, a2.into()), + Sys::SCHED_YIELD => self.unimplemented("yield", Ok(0)), + Sys::SCHED_GETAFFINITY => self.unimplemented("sched_getaffinity", Ok(0)), // socket // Sys::SOCKET => self.sys_socket(a0, a1, a2), diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index 0fc529b90..3b733c920 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -147,13 +147,13 @@ impl Syscall<'_> { argv: UserInPtr>, envp: UserInPtr>, ) -> SysResult { - info!( - "execve: path: {:?}, argv: {:?}, envp: {:?}", - path, argv, envp - ); let path = path.read_cstring()?; let args = argv.read_cstring_array()?; let envs = envp.read_cstring_array()?; + info!( + "execve: path: {:?}, argv: {:?}, envs: {:?}", + path, argv, envs + ); if args.is_empty() { error!("execve: args is null"); return Err(LxError::EINVAL); From 4011f4bcd5ad17fb893d7177ee1f01cc3f72de3b Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 21:52:05 -0700 Subject: [PATCH 5/8] add test for pipe in single process --- linux-syscall/test/testpipe1.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/linux-syscall/test/testpipe1.c b/linux-syscall/test/testpipe1.c index a60180954..1aff5e91f 100644 --- a/linux-syscall/test/testpipe1.c +++ b/linux-syscall/test/testpipe1.c @@ -17,6 +17,21 @@ int main() int receivep = 0; char w[12]; char r[12]; + + if (pipe(pipefd) == -1) + { + printf("pipe"); + exit(-1); + } + write(pipefd[1], "test", strlen("test")); + close(pipefd[1]); + while (read(pipefd[0], &buf, 1) > 0) + received[receivep++] = buf; + received[receivep] = 0; + receivep = 0; + assert(strcmp(received, "test") == 0); + close(pipefd[0]); + if (pipe(pipefd) == -1) { printf("pipe"); From f1cccaf0dbdbbd4dfe41faf9050ba3008ab85dcd Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 22:06:51 -0700 Subject: [PATCH 6/8] update doc in linux-object::file --- linux-object/src/fs/device.rs | 2 ++ linux-object/src/fs/fcntl.rs | 2 ++ linux-object/src/fs/file.rs | 13 ++++++++++++- linux-object/src/fs/mod.rs | 9 +++++++-- linux-object/src/fs/pseudo.rs | 2 ++ linux-object/src/fs/random.rs | 7 +++++-- linux-object/src/fs/stdio.rs | 7 +++++++ 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/linux-object/src/fs/device.rs b/linux-object/src/fs/device.rs index 8ee7353b0..6cb65eb2c 100644 --- a/linux-object/src/fs/device.rs +++ b/linux-object/src/fs/device.rs @@ -3,9 +3,11 @@ use rcore_fs::dev::*; use spin::RwLock; +/// memory buffer for device pub struct MemBuf(RwLock<&'static mut [u8]>); impl MemBuf { + /// create a MemBuf struct pub fn new(buf: &'static mut [u8]) -> Self { MemBuf(RwLock::new(buf)) } diff --git a/linux-object/src/fs/fcntl.rs b/linux-object/src/fs/fcntl.rs index 75ec0ec7d..f103c11ea 100644 --- a/linux-object/src/fs/fcntl.rs +++ b/linux-object/src/fs/fcntl.rs @@ -8,6 +8,7 @@ use bitflags::bitflags; const F_LINUX_SPECIFIC_BASE: usize = 1024; bitflags! { + /// fcntl flags pub struct FcntlFlags: usize { /// dup const F_DUPFD = 0; @@ -33,6 +34,7 @@ bitflags! { } bitflags! { + /// file operate flags pub struct FileFlags: usize { /// not blocking const O_NONBLOCK = 0o4000; diff --git a/linux-object/src/fs/file.rs b/linux-object/src/fs/file.rs index 0ad037743..1eda49217 100644 --- a/linux-object/src/fs/file.rs +++ b/linux-object/src/fs/file.rs @@ -1,6 +1,6 @@ //! File handle for process -#![allow(dead_code)] +#![allow(dead_code, missing_docs)] use alloc::{boxed::Box, string::String, sync::Arc}; @@ -11,27 +11,38 @@ use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus}; use spin::Mutex; use zircon_object::object::*; +/// file implement struct pub struct File { + /// object base base: KObjectBase, + /// file INode inode: Arc, + /// file open options options: OpenOptions, + /// file path pub path: String, + /// file inner mut data inner: Mutex, } impl_kobject!(File); +/// file inner mut data struct #[derive(Default)] struct FileInner { offset: u64, } +/// file open options struct #[derive(Debug)] pub struct OpenOptions { + /// open as readable pub read: bool, + /// open as writeable pub write: bool, /// Before each write, the file offset is positioned at the end of the file. pub append: bool, + /// non block open pub nonblock: bool, } diff --git a/linux-object/src/fs/mod.rs b/linux-object/src/fs/mod.rs index dbd479779..8a1f91d09 100644 --- a/linux-object/src/fs/mod.rs +++ b/linux-object/src/fs/mod.rs @@ -1,5 +1,5 @@ //! Linux file objects -//#![deny(missing_docs)] +#![deny(missing_docs)] use alloc::{boxed::Box, sync::Arc, vec::Vec}; use rcore_fs::vfs::*; @@ -138,8 +138,9 @@ pub fn create_root_fs(rootfs: Arc) -> Arc { root } -/// ext +/// extension for INode pub trait INodeExt { + /// similar to read, but return a u8 vector fn read_as_vec(&self) -> Result>; } @@ -207,6 +208,9 @@ impl LinuxProcess { } } + /// Lookup INode from the process. + /// + /// see `lookup_inode_at` pub fn lookup_inode(&self, path: &str) -> LxResult> { self.lookup_inode_at(FileDesc::CWD, path, true) } @@ -223,4 +227,5 @@ pub fn split_path(path: &str) -> (&str, &str) { (dir_path, file_name) } +/// the max depth for following a link const FOLLOW_MAX_DEPTH: usize = 1; diff --git a/linux-object/src/fs/pseudo.rs b/linux-object/src/fs/pseudo.rs index 44b8c6d67..244a8b275 100644 --- a/linux-object/src/fs/pseudo.rs +++ b/linux-object/src/fs/pseudo.rs @@ -5,12 +5,14 @@ use core::any::Any; use rcore_fs::vfs::*; +/// Pseudo INode struct pub struct Pseudo { content: Vec, type_: FileType, } impl Pseudo { + /// create a Pseudo INode pub fn new(s: &str, type_: FileType) -> Self { Pseudo { content: Vec::from(s.as_bytes()), diff --git a/linux-object/src/fs/random.rs b/linux-object/src/fs/random.rs index 7628fdde8..5f3cbaea8 100644 --- a/linux-object/src/fs/random.rs +++ b/linux-object/src/fs/random.rs @@ -6,10 +6,12 @@ use core::any::Any; use rcore_fs::vfs::*; use spin::Mutex; +/// random INode data struct pub struct RandomINodeData { seed: u32, } +/// random INode struct #[derive(Clone)] pub struct RandomINode { data: Arc>, @@ -17,8 +19,9 @@ pub struct RandomINode { } impl RandomINode { - // urandom -> secure=true - // random -> secure=false + /// create a random INode + /// - urandom -> secure = true + /// - random -> secure = false pub fn new(secure: bool) -> RandomINode { RandomINode { secure, diff --git a/linux-object/src/fs/stdio.rs b/linux-object/src/fs/stdio.rs index fa801148f..66492d0fb 100644 --- a/linux-object/src/fs/stdio.rs +++ b/linux-object/src/fs/stdio.rs @@ -10,10 +10,13 @@ use rcore_fs::vfs::*; use spin::Mutex; lazy_static! { + /// STDIN global reference pub static ref STDIN: Arc = Default::default(); + /// STDOUT global reference pub static ref STDOUT: Arc = Default::default(); } +/// Stdin struct, for Stdin buffer #[derive(Default)] pub struct Stdin { buf: Mutex>, @@ -21,10 +24,12 @@ pub struct Stdin { } impl Stdin { + /// push a char in Stdin buffer pub fn push(&self, c: char) { self.buf.lock().push_back(c); // self.pushed.notify_one(); } + /// pop a char in Stdin buffer pub fn pop(&self) -> char { loop { let mut buf_lock = self.buf.lock(); @@ -35,11 +40,13 @@ impl Stdin { } } } + /// specify whether the Stdin buffer is readable pub fn can_read(&self) -> bool { self.buf.lock().len() > 0 } } +/// Stdout struct, empty now #[derive(Default)] pub struct Stdout; From 73e4872bc174396d05e6e8c56b72be33589f2353 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 12 Aug 2020 03:16:31 -0700 Subject: [PATCH 7/8] update doc in loader --- linux-object/src/error.rs | 1 + linux-object/src/fs/file.rs | 24 +++++++++++++++++++++++- linux-object/src/loader/abi.rs | 12 ++++++++++++ linux-object/src/loader/mod.rs | 6 ++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/linux-object/src/error.rs b/linux-object/src/error.rs index 316256a48..412d816f0 100644 --- a/linux-object/src/error.rs +++ b/linux-object/src/error.rs @@ -6,6 +6,7 @@ use zircon_object::ZxError; pub type LxResult = Result; pub type SysResult = LxResult; +/// Linux error flag defination #[allow(dead_code)] #[repr(isize)] #[derive(Debug)] diff --git a/linux-object/src/fs/file.rs b/linux-object/src/fs/file.rs index 1eda49217..d3ee0a4d4 100644 --- a/linux-object/src/fs/file.rs +++ b/linux-object/src/fs/file.rs @@ -1,6 +1,6 @@ //! File handle for process -#![allow(dead_code, missing_docs)] +#![allow(dead_code)] use alloc::{boxed::Box, string::String, sync::Arc}; @@ -46,14 +46,19 @@ pub struct OpenOptions { pub nonblock: bool, } +/// file seek type #[derive(Debug)] pub enum SeekFrom { + /// seek from start point Start(u64), + /// seek from end End(i64), + /// seek from current Current(i64), } impl File { + /// create a file struct pub fn new(inode: Arc, options: OpenOptions, path: String) -> Arc { Arc::new(File { base: KObjectBase::new(), @@ -64,6 +69,7 @@ impl File { }) } + /// read from file pub fn read(&self, buf: &mut [u8]) -> LxResult { let mut inner = self.inner.lock(); let len = self.read_at(inner.offset, buf)?; @@ -71,6 +77,7 @@ impl File { Ok(len) } + /// read from file at given offset pub fn read_at(&self, offset: u64, buf: &mut [u8]) -> LxResult { if !self.options.read { return Err(LxError::EBADF); @@ -93,6 +100,7 @@ impl File { Ok(len) } + /// write to file pub fn write(&self, buf: &[u8]) -> LxResult { let mut inner = self.inner.lock(); let offset = if self.options.append { @@ -105,6 +113,7 @@ impl File { Ok(len) } + /// write to file at given offset pub fn write_at(&self, offset: u64, buf: &[u8]) -> LxResult { if !self.options.write { return Err(LxError::EBADF); @@ -113,6 +122,7 @@ impl File { Ok(len) } + /// seek from given type and offset pub fn seek(&self, pos: SeekFrom) -> LxResult { let mut inner = self.inner.lock(); inner.offset = match pos { @@ -123,6 +133,7 @@ impl File { Ok(inner.offset) } + /// resize the file pub fn set_len(&self, len: u64) -> LxResult { if !self.options.write { return Err(LxError::EBADF); @@ -131,26 +142,31 @@ impl File { Ok(()) } + /// Sync all data and metadata pub fn sync_all(&self) -> LxResult { self.inode.sync_all()?; Ok(()) } + /// Sync data (not include metadata) pub fn sync_data(&self) -> LxResult { self.inode.sync_data()?; Ok(()) } + /// get metadata of file pub fn metadata(&self) -> LxResult { let metadata = self.inode.metadata()?; Ok(metadata) } + /// lookup the file following the link pub fn lookup_follow(&self, path: &str, max_follow: usize) -> LxResult> { let inode = self.inode.lookup_follow(path, max_follow)?; Ok(inode) } + /// get the name of dir entry pub fn read_entry(&self) -> LxResult { if !self.options.read { return Err(LxError::EBADF); @@ -161,24 +177,30 @@ impl File { Ok(name) } + /// wait for some event on a file pub fn poll(&self) -> LxResult { let status = self.inode.poll()?; Ok(status) } + /// wait for some event on a file using async pub async fn async_poll(&self) -> LxResult { Ok(self.inode.async_poll().await?) } + /// manipulates the underlying device parameters of special files pub fn io_control(&self, cmd: u32, arg: usize) -> LxResult { self.inode.io_control(cmd, arg)?; Ok(0) } + /// get INode of this file pub fn inode(&self) -> Arc { self.inode.clone() } + /// manipulate file descriptor + /// unimplemented pub fn fcntl(&self, cmd: usize, arg: usize) -> LxResult { if arg & 0x800 > 0 && cmd == 4 { unimplemented!() diff --git a/linux-object/src/loader/abi.rs b/linux-object/src/loader/abi.rs index bf76525b6..6869d3592 100644 --- a/linux-object/src/loader/abi.rs +++ b/linux-object/src/loader/abi.rs @@ -8,13 +8,18 @@ use core::mem::{align_of, size_of}; use core::ops::Deref; use core::ptr::null; +/// process init information pub struct ProcInitInfo { + /// args strings pub args: Vec, + /// environment strings pub envs: Vec, + /// auxiliary pub auxv: BTreeMap, } impl ProcInitInfo { + /// push process init information into stack pub fn push_at(&self, stack_top: usize) -> Stack { let mut writer = Stack::new(stack_top); // from stack_top: @@ -55,13 +60,18 @@ impl ProcInitInfo { } } +/// program stack pub struct Stack { + /// stack pointer sp: usize, + /// stack top stack_top: usize, + /// stack data buffer data: Vec, } impl Stack { + /// create a stack fn new(sp: usize) -> Self { let mut data = Vec::with_capacity(0x4000); unsafe { @@ -73,6 +83,7 @@ impl Stack { data, } } + /// push slice into stack fn push_slice(&mut self, vs: &[T]) { self.sp -= vs.len() * size_of::(); self.sp -= self.sp % align_of::(); @@ -83,6 +94,7 @@ impl Stack { } .copy_from_slice(vs); } + /// push str into stack fn push_str(&mut self, s: &str) { self.push_slice(&[b'\0']); self.push_slice(s.as_bytes()); diff --git a/linux-object/src/loader/mod.rs b/linux-object/src/loader/mod.rs index 89ddfca84..4fcda3f62 100644 --- a/linux-object/src/loader/mod.rs +++ b/linux-object/src/loader/mod.rs @@ -1,4 +1,6 @@ //! Linux ELF Program Loader +#![deny(missing_docs)] + use { crate::error::LxResult, crate::fs::INodeExt, @@ -12,12 +14,16 @@ mod abi; /// Linux ELF Program Loader. pub struct LinuxElfLoader { + /// syscall entry pub syscall_entry: usize, + /// stack page number pub stack_pages: usize, + /// root inode of LinuxElfLoader pub root_inode: Arc, } impl LinuxElfLoader { + /// load a Linux ElfFile and return a tuple of (entry,sp) pub fn load( &self, vmar: &Arc, From fe928819efc42d445b9a2e9002e6312197872c18 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Wed, 12 Aug 2020 03:37:37 -0700 Subject: [PATCH 8/8] update doc for linux-object --- linux-object/src/error.rs | 57 +++++++++++++++++++++++++++++++++++-- linux-object/src/fs/file.rs | 2 +- linux-object/src/lib.rs | 8 +++++- linux-object/src/process.rs | 6 ++++ linux-object/src/thread.rs | 5 ++++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/linux-object/src/error.rs b/linux-object/src/error.rs index 412d816f0..82cc0d480 100644 --- a/linux-object/src/error.rs +++ b/linux-object/src/error.rs @@ -1,64 +1,115 @@ -//! Linux error flags +//! Linux error codes use core::fmt; use rcore_fs::vfs::FsError; use zircon_object::ZxError; +/// Linux Result defination pub type LxResult = Result; +/// SysResult Result defination (same as Linux Result) pub type SysResult = LxResult; -/// Linux error flag defination +/// Linux error codes defination #[allow(dead_code)] #[repr(isize)] #[derive(Debug)] pub enum LxError { + /// Undefined EUNDEF = 0, + /// Operation not permitted EPERM = 1, + /// No such file or directory ENOENT = 2, + /// No such process ESRCH = 3, + /// Interrupted system call EINTR = 4, + /// I/O error EIO = 5, + /// No such device or address ENXIO = 6, + /// Arg list too long E2BIG = 7, + /// Exec format error ENOEXEC = 8, + /// Bad file number EBADF = 9, + /// No child processes ECHILD = 10, + /// Try again EAGAIN = 11, + /// Out of memory ENOMEM = 12, + /// Permission denied EACCES = 13, + /// Bad address EFAULT = 14, + /// Block device required ENOTBLK = 15, + /// Device or resource busy EBUSY = 16, + /// File exists EEXIST = 17, + /// Cross-device link EXDEV = 18, + /// No such device ENODEV = 19, + /// Not a directory ENOTDIR = 20, + /// Is a directory EISDIR = 21, + /// Invalid argument EINVAL = 22, + /// File table overflow ENFILE = 23, + /// Too many open files EMFILE = 24, + /// Not a tty device ENOTTY = 25, + /// Text file busy ETXTBSY = 26, + /// File too large EFBIG = 27, + /// No space left on device ENOSPC = 28, + /// Illegal seek ESPIPE = 29, + /// Read-only file system EROFS = 30, + /// Too many links EMLINK = 31, + /// Broken pipe EPIPE = 32, + /// Math argument out of domain EDOM = 33, + /// Math result not representable ERANGE = 34, + /// Resource deadlock would occur EDEADLK = 35, + /// Filename too long ENAMETOOLONG = 36, + /// No record locks available ENOLCK = 37, + /// Function not implemented ENOSYS = 38, + /// Directory not empty ENOTEMPTY = 39, + /// Too many symbolic links encountered ELOOP = 40, - ENOTSOCK = 80, + /// Socket operation on non-socket + ENOTSOCK = 88, + /// Protocol not available ENOPROTOOPT = 92, + /// Protocol family not supported EPFNOSUPPORT = 96, + /// Address family not supported by protocol EAFNOSUPPORT = 97, + /// No buffer space available ENOBUFS = 105, + /// Transport endpoint is already connected EISCONN = 106, + /// Transport endpoint is not connected ENOTCONN = 107, + /// Connection refused ECONNREFUSED = 111, } diff --git a/linux-object/src/fs/file.rs b/linux-object/src/fs/file.rs index d3ee0a4d4..477126b81 100644 --- a/linux-object/src/fs/file.rs +++ b/linux-object/src/fs/file.rs @@ -49,7 +49,7 @@ pub struct OpenOptions { /// file seek type #[derive(Debug)] pub enum SeekFrom { - /// seek from start point + /// seek from start point Start(u64), /// seek from end End(i64), diff --git a/linux-object/src/lib.rs b/linux-object/src/lib.rs index c33b3e624..28366d56d 100644 --- a/linux-object/src/lib.rs +++ b/linux-object/src/lib.rs @@ -1,7 +1,13 @@ //! Linux kernel objects #![no_std] -#![deny(warnings, unsafe_code, unused_must_use, unreachable_patterns)] +#![deny( + warnings, + unsafe_code, + unused_must_use, + unreachable_patterns, + missing_docs +)] #![feature(bool_to_option)] extern crate alloc; diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index eefabf46d..caed5f38b 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -20,9 +20,13 @@ use zircon_object::{ ZxResult, }; +/// Process extension for linux pub trait ProcessExt { + /// create Linux process fn create_linux(job: &Arc, rootfs: Arc) -> ZxResult>; + /// get linux process fn linux(&self) -> &LinuxProcess; + /// fork from current linux process fn fork_from(parent: &Arc, vfork: bool) -> ZxResult>; } @@ -128,6 +132,7 @@ pub struct LinuxProcess { inner: Mutex, } +/// Linux process mut inner data #[derive(Default)] struct LinuxProcessInner { /// Execute path @@ -144,6 +149,7 @@ struct LinuxProcessInner { children: HashMap>, } +/// process exit code defination pub type ExitCode = i32; impl LinuxProcess { diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index 8b0bed59c..b3a514ab0 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -8,10 +8,15 @@ use spin::{Mutex, MutexGuard}; use zircon_object::task::{Process, Thread}; use zircon_object::ZxResult; +/// Thread extension for linux pub trait ThreadExt { + /// create linux thread fn create_linux(proc: &Arc) -> ZxResult>; + /// lock and get Linux thread fn lock_linux(&self) -> MutexGuard<'_, LinuxThread>; + /// Set pointer to thread ID. fn set_tid_address(&self, tidptr: UserOutPtr); + /// exit linux thread fn exit_linux(&self, exit_code: i32); }