From f0c94c5280d1565be4817271e1203365385842df Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Sat, 8 Aug 2020 08:21:40 -0700 Subject: [PATCH 01/10] add time syscalls --- linux-syscall/Cargo.toml | 3 + linux-syscall/src/time.rs | 168 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 166 insertions(+), 5 deletions(-) diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index 3e2609915..ee47e933e 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -15,3 +15,6 @@ numeric-enum-macro = "0.2" zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object" } kernel-hal = { path = "../kernel-hal" } +rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } +lazy_static = { version = "1.4", features = ["spin_no_std"] } + diff --git a/linux-syscall/src/time.rs b/linux-syscall/src/time.rs index 26a73dbe2..76df0b58a 100644 --- a/linux-syscall/src/time.rs +++ b/linux-syscall/src/time.rs @@ -1,9 +1,18 @@ //! Syscalls for time //! - clock_gettime +#![allow(dead_code)] +#![allow(unused_must_use)] +#![allow(missing_docs)] + +const USEC_PER_TICK: usize = 10000; use crate::Syscall; -use kernel_hal::{timer_now, user::UserOutPtr}; +use alloc::sync::Arc; +use core::time::Duration; +use kernel_hal::{timer_now, user::UserInPtr, user::UserOutPtr}; +use linux_object::error::LxError; use linux_object::error::SysResult; +use rcore_fs::vfs::*; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -19,14 +28,163 @@ impl Syscall<'_> { /// if buffer is non-NULL, stores it in the struct timespec pointed to by buffer pub fn sys_clock_gettime(&self, clock: usize, mut buf: UserOutPtr) -> SysResult { info!("clock_gettime: id={:?} buf={:?}", clock, buf); + // TODO: handle clock_settime + let ts = TimeSpec::new(); + buf.write(ts)?; + + Ok(0) + } + + pub fn sys_gettimeofday( + &mut self, + mut tv: UserOutPtr, + tz: UserInPtr, + ) -> SysResult { + info!("gettimeofday: tv: {:?}, tz: {:?}", tv, tz); + // don't support tz + if !tz.is_null() { + return Err(LxError::EINVAL); + } + + let timeval = TimeVal::new(); + tv.write(timeval)?; + Ok(0) + } + + #[cfg(target_arch = "x86_64")] + pub fn sys_time(&mut self, mut time: UserOutPtr) -> SysResult { + let sec = TimeSpec::new().sec; + time.write(sec as u64)?; + Ok(sec) + } + + pub fn sys_getrusage(&mut self, who: usize, mut rusage: UserOutPtr) -> SysResult { + info!("getrusage: who: {}, rusage: {:?}", who, rusage); + + let new_rusage = RUsage { + utime: TimeVal::new(), + stime: TimeVal::new(), + }; + rusage.write(new_rusage); + Ok(0) + } + + pub fn sys_times(&mut self, mut buf: UserOutPtr) -> SysResult { + info!("times: buf: {:?}", buf); + + let tick = 0; // unsafe { crate::trap::TICK as u64 }; + + let new_buf = Tms { + tms_utime: 0, + tms_stime: 0, + tms_cutime: 0, + tms_cstime: 0, + }; + // TODO: TICKS + buf.write(new_buf); + Ok(tick as usize) + } +} + +// 1ms msec +// 1us usec +// 1ns nsec +const USEC_PER_SEC: u64 = 1_000_000; +const MSEC_PER_SEC: u64 = 1_000; +const USEC_PER_MSEC: u64 = 1_000; +const NSEC_PER_USEC: u64 = 1_000; +const NSEC_PER_MSEC: u64 = 1_000_000; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TimeVal { + sec: usize, + usec: usize, +} + +impl TimeVal { + pub fn new() -> TimeVal { + TimeSpec::new().into() + } + pub fn to_msec(&self) -> u64 { + (self.sec as u64) * MSEC_PER_SEC + (self.usec as u64) / USEC_PER_MSEC + } +} + +impl TimeSpec { + pub fn new() -> TimeSpec { let time = timer_now(); - let ts = TimeSpec { + TimeSpec { sec: time.as_secs() as usize, nsec: (time.as_nanos() % 1_000_000_000) as usize, - }; - buf.write(ts)?; + } + } - Ok(0) + pub fn to_msec(&self) -> u64 { + (self.sec as u64) * MSEC_PER_SEC + (self.nsec as u64) / NSEC_PER_MSEC + } + + // TODO: more precise; update when write + pub fn update(inode: &Arc) { + let now = TimeSpec::new().into(); + if let Ok(mut metadata) = inode.metadata() { + metadata.atime = now; + metadata.mtime = now; + metadata.ctime = now; + // silently fail for device file + inode.set_metadata(&metadata).ok(); + } + } + + pub fn is_zero(&self) -> bool { + self.sec == 0 && self.nsec == 0 + } +} + +impl Into for TimeSpec { + fn into(self) -> Timespec { + Timespec { + sec: self.sec as i64, + nsec: self.nsec as i32, + } + } +} + +impl Into for TimeSpec { + fn into(self) -> Duration { + Duration::new(self.sec as u64, self.nsec as u32) + } +} + +impl Into for TimeSpec { + fn into(self) -> TimeVal { + TimeVal { + sec: self.sec, + usec: self.nsec / NSEC_PER_USEC as usize, + } } } + +// ignore other fields for now +#[repr(C)] +pub struct RUsage { + utime: TimeVal, + stime: TimeVal, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Tms { + tms_utime: u64, /* user time */ + tms_stime: u64, /* system time */ + tms_cutime: u64, /* user time of children */ + tms_cstime: u64, /* system time of children */ +} + +#[cfg(test)] +mod test { + + #[test] + fn test_time() {} +} From fd4d3692c51b5e94683e31b2039a14ecbcd51f39 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Sun, 9 Aug 2020 22:36:07 -0700 Subject: [PATCH 02/10] update some doc and fix clippy --- linux-syscall/src/lib.rs | 8 ++-- linux-syscall/src/time.rs | 95 ++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index e84901ae0..4e7ee0487 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -181,7 +181,7 @@ impl Syscall<'_> { // time // Sys::NANOSLEEP => self.sys_nanosleep(a0.into()), Sys::SETITIMER => self.unimplemented("setitimer", Ok(0)), - // Sys::GETTIMEOFDAY => self.sys_gettimeofday(a0.into(), a1.into()), + Sys::GETTIMEOFDAY => self.sys_gettimeofday(a0.into(), a1.into()), Sys::CLOCK_GETTIME => self.sys_clock_gettime(a0, a1.into()), // sem @@ -199,9 +199,9 @@ impl Syscall<'_> { Sys::UMASK => self.unimplemented("umask", Ok(0o777)), // Sys::GETRLIMIT => self.sys_getrlimit(), // Sys::SETRLIMIT => self.sys_setrlimit(), - // Sys::GETRUSAGE => self.sys_getrusage(a0, a1.into()), + Sys::GETRUSAGE => self.sys_getrusage(a0, a1.into()), // Sys::SYSINFO => self.sys_sysinfo(a0.into()), - // Sys::TIMES => self.sys_times(a0.into()), + Sys::TIMES => self.sys_times(a0.into()), Sys::GETUID => self.unimplemented("getuid", Ok(0)), Sys::GETGID => self.unimplemented("getgid", Ok(0)), Sys::SETUID => self.unimplemented("setuid", Ok(0)), @@ -260,7 +260,7 @@ impl Syscall<'_> { // Sys::CHMOD => self.unimplemented("chmod", Ok(0)), // Sys::CHOWN => self.unimplemented("chown", Ok(0)), Sys::ARCH_PRCTL => self.sys_arch_prctl(a0 as _, a1), - // Sys::TIME => self.sys_time(a0 as *mut u64), + Sys::TIME => self.sys_time(a0.into()), // Sys::EPOLL_CREATE => self.sys_epoll_create(a0), // Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3), _ => self.unknown_syscall(sys_type), diff --git a/linux-syscall/src/time.rs b/linux-syscall/src/time.rs index 76df0b58a..f8feac696 100644 --- a/linux-syscall/src/time.rs +++ b/linux-syscall/src/time.rs @@ -1,8 +1,5 @@ //! Syscalls for time //! - clock_gettime -#![allow(dead_code)] -#![allow(unused_must_use)] -#![allow(missing_docs)] const USEC_PER_TICK: usize = 10000; @@ -14,6 +11,7 @@ use linux_object::error::LxError; use linux_object::error::SysResult; use rcore_fs::vfs::*; +/// TimeSpec struct for clock_gettime, similar to Timespec #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TimeSpec { @@ -23,6 +21,16 @@ pub struct TimeSpec { nsec: usize, } +/// TimeVal struct for gettimeofday +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TimeVal { + /// seconds + sec: usize, + /// microsecond + usec: usize, +} + impl Syscall<'_> { /// finds the resolution (precision) of the specified clock clockid, and, /// if buffer is non-NULL, stores it in the struct timespec pointed to by buffer @@ -32,9 +40,12 @@ impl Syscall<'_> { let ts = TimeSpec::new(); buf.write(ts)?; + info!("TimeSpec: {:?}", ts); + Ok(0) } + /// get the time with second and microseconds pub fn sys_gettimeofday( &mut self, mut tv: UserOutPtr, @@ -48,16 +59,25 @@ impl Syscall<'_> { let timeval = TimeVal::new(); tv.write(timeval)?; + + info!("TimeVal: {:?}", timeval); + Ok(0) } + /// get time in seconds #[cfg(target_arch = "x86_64")] pub fn sys_time(&mut self, mut time: UserOutPtr) -> SysResult { + info!("time: time: {:?}", time); let sec = TimeSpec::new().sec; time.write(sec as u64)?; Ok(sec) } + /// get resource usage + /// currently only support ru_utime and ru_stime: + /// - `ru_utime`: user CPU time used + /// - `ru_stime`: system CPU time used pub fn sys_getrusage(&mut self, who: usize, mut rusage: UserOutPtr) -> SysResult { info!("getrusage: who: {}, rusage: {:?}", who, rusage); @@ -65,14 +85,15 @@ impl Syscall<'_> { utime: TimeVal::new(), stime: TimeVal::new(), }; - rusage.write(new_rusage); + rusage.write(new_rusage)?; Ok(0) } + /// stores the current process times in the struct tms that buf points to pub fn sys_times(&mut self, mut buf: UserOutPtr) -> SysResult { info!("times: buf: {:?}", buf); - let tick = 0; // unsafe { crate::trap::TICK as u64 }; + let tick = (TimeVal::new().sec * 1_000_000 + TimeVal::new().usec) / USEC_PER_TICK; let new_buf = Tms { tms_utime: 0, @@ -80,39 +101,21 @@ impl Syscall<'_> { tms_cutime: 0, tms_cstime: 0, }; - // TODO: TICKS - buf.write(new_buf); + + buf.write(new_buf)?; Ok(tick as usize) } } -// 1ms msec -// 1us usec -// 1ns nsec -const USEC_PER_SEC: u64 = 1_000_000; -const MSEC_PER_SEC: u64 = 1_000; -const USEC_PER_MSEC: u64 = 1_000; -const NSEC_PER_USEC: u64 = 1_000; -const NSEC_PER_MSEC: u64 = 1_000_000; - -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TimeVal { - sec: usize, - usec: usize, -} - impl TimeVal { + /// create TimeVal pub fn new() -> TimeVal { TimeSpec::new().into() } - - pub fn to_msec(&self) -> u64 { - (self.sec as u64) * MSEC_PER_SEC + (self.usec as u64) / USEC_PER_MSEC - } } impl TimeSpec { + /// create TimeSpec pub fn new() -> TimeSpec { let time = timer_now(); TimeSpec { @@ -121,11 +124,8 @@ impl TimeSpec { } } - pub fn to_msec(&self) -> u64 { - (self.sec as u64) * MSEC_PER_SEC + (self.nsec as u64) / NSEC_PER_MSEC - } - - // TODO: more precise; update when write + /// update TimeSpec for a file inode + /// TODO: more precise; update when write pub fn update(inode: &Arc) { let now = TimeSpec::new().into(); if let Ok(mut metadata) = inode.metadata() { @@ -136,10 +136,6 @@ impl TimeSpec { inode.set_metadata(&metadata).ok(); } } - - pub fn is_zero(&self) -> bool { - self.sec == 0 && self.nsec == 0 - } } impl Into for TimeSpec { @@ -161,18 +157,34 @@ impl Into for TimeSpec { fn into(self) -> TimeVal { TimeVal { sec: self.sec, - usec: self.nsec / NSEC_PER_USEC as usize, + usec: self.nsec / 1_000 as usize, } } } -// ignore other fields for now +impl Default for TimeVal { + fn default() -> Self { + Self::new() + } +} + +impl Default for TimeSpec { + fn default() -> Self { + Self::new() + } +} + +/// RUsage for sys_getrusage() +/// ignore other fields for now #[repr(C)] pub struct RUsage { + /// user CPU time used utime: TimeVal, + /// system CPU time used stime: TimeVal, } +/// Tms for times() #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Tms { @@ -181,10 +193,3 @@ pub struct Tms { tms_cutime: u64, /* user time of children */ tms_cstime: u64, /* system time of children */ } - -#[cfg(test)] -mod test { - - #[test] - fn test_time() {} -} From 15a6e6c02fb4583e0f71c9ecab79f02357627c06 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Mon, 10 Aug 2020 01:49:04 -0700 Subject: [PATCH 03/10] touch command can create file! --- linux-loader/src/main.rs | 6 ++++ linux-object/src/fs/fcntl.rs | 24 +++++++++++++ linux-object/src/fs/mod.rs | 2 ++ linux-syscall/src/file/file.rs | 63 ++++++++++++++++++++++++++++++++++ linux-syscall/src/lib.rs | 2 +- linux-syscall/src/time.rs | 6 ++-- 6 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 linux-object/src/fs/fcntl.rs diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index 6ddac480d..379a88a4d 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -89,6 +89,12 @@ mod tests { test("/bin/busybox dirname /bin/busybox").await; } + #[async_std::test] + async fn test_create_remove_file() { + test("/bin/busybox touch test").await; + test("/bin/busybox rm test").await; + } + #[async_std::test] async fn test_create_remove_dir() { test("/bin/busybox mkdir test").await; diff --git a/linux-object/src/fs/fcntl.rs b/linux-object/src/fs/fcntl.rs new file mode 100644 index 000000000..fce916923 --- /dev/null +++ b/linux-object/src/fs/fcntl.rs @@ -0,0 +1,24 @@ +//! consts for fctnl +//! currently support x86_64 only +//! copy from fcntl.h (from rCore) +#![allow(dead_code)] + +pub const F_DUPFD: usize = 0; /* dup */ +pub const F_GETFD: usize = 1; /* get close_on_exec */ +pub const F_SETFD: usize = 2; /* set/clear close_on_exec */ +pub const F_GETFL: usize = 3; /* get file->f_flags */ +pub const F_SETFL: usize = 4; /* set file->f_flags */ +pub const F_GETLK: usize = 5; /* Get record locking info. */ +pub const F_SETLK: usize = 6; /* Set record locking info (non-blocking). */ +pub const F_SETLKW: usize = 7; /* Set record locking info (blocking). */ + +const F_LINUX_SPECIFIC_BASE: usize = 1024; + +pub const FD_CLOEXEC: usize = 1; +pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6; + +pub const O_NONBLOCK: usize = 0o4000; +pub const O_APPEND: usize = 0o2000; +pub const O_CLOEXEC: usize = 0o2000000; /* set close_on_exec */ + +pub const AT_SYMLINK_NOFOLLOW: usize = 0x100; diff --git a/linux-object/src/fs/mod.rs b/linux-object/src/fs/mod.rs index 709a73a81..a2e3cc1a4 100644 --- a/linux-object/src/fs/mod.rs +++ b/linux-object/src/fs/mod.rs @@ -6,6 +6,7 @@ use rcore_fs_mountfs::MountFS; use rcore_fs_ramfs::RamFS; pub use self::device::*; +pub use self::fcntl::*; pub use self::file::*; pub use self::pipe::*; pub use self::pseudo::*; @@ -20,6 +21,7 @@ use downcast_rs::impl_downcast; use zircon_object::object::*; mod device; +mod fcntl; mod file; mod ioctl; mod pipe; diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index 82f090e5a..2f8e3290d 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -10,6 +10,7 @@ //! - access, faccessat use super::*; +use crate::time::*; impl Syscall<'_> { /// Reads from a specified file using a file descriptor. Before using this call, @@ -329,4 +330,66 @@ impl Syscall<'_> { let _inode = proc.lookup_inode_at(dirfd, &path, follow)?; Ok(0) } + + /// change file timestamps with nanosecond precision + pub fn sys_utimensat( + &mut self, + dirfd: usize, + pathname: UserInPtr, + times: UserInOutPtr<[TimeSpec; 2]>, + flags: usize, + ) -> SysResult { + info!( + "utimensat(raw): dirfd: {:?}, pathname: {:?}, times: {:?}, flags: {:#x}", + dirfd, pathname, times, flags + ); + const UTIME_NOW: usize = 0x3fffffff; + const UTIME_OMIT: usize = 0x3ffffffe; + let proc = self.linux_process(); + let mut times = if times.is_null() { + let epoch = TimeSpec::new(); + [epoch, epoch] + } else { + let times = times.read()?; + [times[0], times[1]] + }; + let inode = if pathname.is_null() { + let fd = dirfd; + info!("futimens: fd: {}, times: {:?}", fd, times); + proc.get_file(fd.into())?.inode() + } else { + let pathname = pathname.read_cstring()?; + info!( + "utimensat: dirfd: {:?}, pathname: {:?}, times: {:?}, flags: {:#x}", + dirfd, pathname, times, flags + ); + let follow = match flags { + 0 => true, + AT_SYMLINK_NOFOLLOW => false, + _ => return Err(LxError::EINVAL), + }; + proc.lookup_inode_at(dirfd.into(), &pathname[..], follow)? + }; + let mut metadata = inode.metadata()?; + if times[0].nsec != UTIME_OMIT { + if times[0].nsec == UTIME_NOW { + times[0] = TimeSpec::new(); + } + metadata.atime = rcore_fs::vfs::Timespec { + sec: times[0].sec as i64, + nsec: times[0].nsec as i32, + }; + } + if times[1].nsec != UTIME_OMIT { + if times[1].nsec == UTIME_NOW { + times[1] = TimeSpec::new(); + } + metadata.mtime = rcore_fs::vfs::Timespec { + sec: times[1].sec as i64, + nsec: times[1].nsec as i32, + }; + } + inode.set_metadata(&metadata)?; + Ok(0) + } } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 4e7ee0487..fe0601f73 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -113,7 +113,7 @@ impl Syscall<'_> { Sys::FACCESSAT => self.sys_faccessat(a0.into(), a1.into(), a2, a3), Sys::DUP3 => self.sys_dup2(a0.into(), a1.into()), // TODO: handle `flags` Sys::PIPE2 => self.sys_pipe(a0.into()), // TODO: handle `flags` - Sys::UTIMENSAT => self.unimplemented("utimensat", Ok(0)), + Sys::UTIMENSAT => self.sys_utimensat(a0.into(), a1.into(), a2.into(), a3.into()), Sys::COPY_FILE_RANGE => { self.sys_copy_file_range(a0.into(), a1.into(), a2.into(), a3.into(), a4, a5) } diff --git a/linux-syscall/src/time.rs b/linux-syscall/src/time.rs index f8feac696..51291ff79 100644 --- a/linux-syscall/src/time.rs +++ b/linux-syscall/src/time.rs @@ -16,9 +16,9 @@ use rcore_fs::vfs::*; #[derive(Debug, Copy, Clone)] pub struct TimeSpec { /// seconds - sec: usize, + pub sec: usize, /// nano seconds - nsec: usize, + pub nsec: usize, } /// TimeVal struct for gettimeofday @@ -103,6 +103,8 @@ impl Syscall<'_> { }; buf.write(new_buf)?; + + info!("tick: {:?}", tick); Ok(tick as usize) } } From 7f14ac0269695255de196e7cb65a8158a43aad9b Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Mon, 10 Aug 2020 01:55:50 -0700 Subject: [PATCH 04/10] fix clippy --- linux-syscall/src/file/file.rs | 8 ++++---- linux-syscall/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index 2f8e3290d..70474490c 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -334,7 +334,7 @@ impl Syscall<'_> { /// change file timestamps with nanosecond precision pub fn sys_utimensat( &mut self, - dirfd: usize, + dirfd: FileDesc, pathname: UserInPtr, times: UserInOutPtr<[TimeSpec; 2]>, flags: usize, @@ -355,8 +355,8 @@ impl Syscall<'_> { }; let inode = if pathname.is_null() { let fd = dirfd; - info!("futimens: fd: {}, times: {:?}", fd, times); - proc.get_file(fd.into())?.inode() + info!("futimens: fd: {:?}, times: {:?}", fd, times); + proc.get_file(fd)?.inode() } else { let pathname = pathname.read_cstring()?; info!( @@ -368,7 +368,7 @@ impl Syscall<'_> { AT_SYMLINK_NOFOLLOW => false, _ => return Err(LxError::EINVAL), }; - proc.lookup_inode_at(dirfd.into(), &pathname[..], follow)? + proc.lookup_inode_at(dirfd, &pathname[..], follow)? }; let mut metadata = inode.metadata()?; if times[0].nsec != UTIME_OMIT { diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index fe0601f73..6ebbb5404 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -113,7 +113,7 @@ impl Syscall<'_> { Sys::FACCESSAT => self.sys_faccessat(a0.into(), a1.into(), a2, a3), Sys::DUP3 => self.sys_dup2(a0.into(), a1.into()), // TODO: handle `flags` Sys::PIPE2 => self.sys_pipe(a0.into()), // TODO: handle `flags` - Sys::UTIMENSAT => self.sys_utimensat(a0.into(), a1.into(), a2.into(), a3.into()), + Sys::UTIMENSAT => self.sys_utimensat(a0.into(), a1.into(), a2.into(), a3), Sys::COPY_FILE_RANGE => { self.sys_copy_file_range(a0.into(), a1.into(), a2.into(), a3.into(), a4, a5) } From 7744dc4131256040a8e1b2afade8faa9e95a8296 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Mon, 10 Aug 2020 07:02:37 -0700 Subject: [PATCH 05/10] update file tests for judging --- linux-loader/src/main.rs | 18 ++++++++++++++++++ linux-syscall/test/testpipe1.c | 16 ++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index 379a88a4d..db788dc0c 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -51,6 +51,7 @@ fn init_logger() { #[cfg(test)] mod tests { use super::*; + use std::{fs,io}; /// test with cmd line async fn test(cmdline: &str) { @@ -91,14 +92,22 @@ mod tests { #[async_std::test] async fn test_create_remove_file() { + fs::read("../rootfs/test").unwrap_err(); test("/bin/busybox touch test").await; + fs::read("../rootfs/test").unwrap(); + test("/bin/busybox touch test").await; + fs::read("../rootfs/test").unwrap(); test("/bin/busybox rm test").await; + fs::read("../rootfs/test").unwrap_err(); } #[async_std::test] async fn test_create_remove_dir() { + fs::read_dir("../rootfs/test").unwrap_err(); test("/bin/busybox mkdir test").await; + fs::read_dir("../rootfs/test").unwrap(); test("/bin/busybox rmdir test").await; + fs::read_dir("../rootfs/test").unwrap_err(); } #[async_std::test] @@ -108,14 +117,20 @@ mod tests { #[async_std::test] async fn test_cp_mv() { + fs::read("../rootfs/etc/hostname.bak").unwrap_err(); test("/bin/busybox cp /etc/hostname /etc/hostname.bak").await; + fs::read("../rootfs/etc/hostname.bak").unwrap(); test("/bin/busybox mv /etc/hostname.bak /etc/hostname.mv").await; + fs::read("../rootfs/etc/hostname.bak").unwrap_err(); } #[async_std::test] async fn test_link() { + fs::read("../rootfs/etc/hostname.ln").unwrap_err(); test("/bin/busybox ln /etc/hostname /etc/hostname.ln").await; + fs::read("../rootfs/etc/hostname.ln").unwrap(); test("/bin/busybox unlink /etc/hostname.ln").await; + fs::read("../rootfs/etc/hostname.ln").unwrap_err(); } #[async_std::test] @@ -128,5 +143,8 @@ mod tests { #[async_std::test] async fn test_pipe() { test("/bin/testpipe1").await; + let str = fs::read_to_string("../rootfs/testpipe.txt").unwrap(); + io::stdout().write(str.as_bytes()).unwrap(); + test("/bin/busybox rm testpipe.txt").await; } } diff --git a/linux-syscall/test/testpipe1.c b/linux-syscall/test/testpipe1.c index f845b4b4f..00c207504 100644 --- a/linux-syscall/test/testpipe1.c +++ b/linux-syscall/test/testpipe1.c @@ -1,7 +1,9 @@ -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include int main() @@ -29,10 +31,12 @@ int main() else if(pid > 0) { close(pipefd[1]); + int fd = open("testpipe.txt", O_WRONLY | O_CREAT); while (read(pipefd[0], &buf, 1) > 0) - write(STDOUT_FILENO, &buf, 1); - write(STDOUT_FILENO, "\n", 1); + write(fd, &buf, 1); + write(fd, "\n", 1); close(pipefd[0]); + close(fd); } return 0; } From d05292969a9ae4eb70b229e22058985a1826291f Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Mon, 10 Aug 2020 07:46:25 -0700 Subject: [PATCH 06/10] add touch test and time test --- linux-loader/src/main.rs | 21 ++++++++++++-------- linux-syscall/src/time.rs | 4 +++- linux-syscall/test/testtime.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 linux-syscall/test/testtime.c diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index db788dc0c..f1edcd6b5 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -51,7 +51,7 @@ fn init_logger() { #[cfg(test)] mod tests { use super::*; - use std::{fs,io}; + use std::{fs, io}; /// test with cmd line async fn test(cmdline: &str) { @@ -92,13 +92,13 @@ mod tests { #[async_std::test] async fn test_create_remove_file() { - fs::read("../rootfs/test").unwrap_err(); - test("/bin/busybox touch test").await; - fs::read("../rootfs/test").unwrap(); - test("/bin/busybox touch test").await; - fs::read("../rootfs/test").unwrap(); - test("/bin/busybox rm test").await; - fs::read("../rootfs/test").unwrap_err(); + fs::read("../rootfs/testfile").unwrap_err(); + test("/bin/busybox touch testfile").await; + fs::read("../rootfs/testfile").unwrap(); + test("/bin/busybox touch testfile").await; + fs::read("../rootfs/testfile").unwrap(); + test("/bin/busybox rm testfile").await; + fs::read("../rootfs/testfile").unwrap_err(); } #[async_std::test] @@ -147,4 +147,9 @@ mod tests { io::stdout().write(str.as_bytes()).unwrap(); test("/bin/busybox rm testpipe.txt").await; } + + #[async_std::test] + async fn test_time() { + test("/bin/testtime").await; + } } diff --git a/linux-syscall/src/time.rs b/linux-syscall/src/time.rs index 51291ff79..58376a44e 100644 --- a/linux-syscall/src/time.rs +++ b/linux-syscall/src/time.rs @@ -93,7 +93,9 @@ impl Syscall<'_> { pub fn sys_times(&mut self, mut buf: UserOutPtr) -> SysResult { info!("times: buf: {:?}", buf); - let tick = (TimeVal::new().sec * 1_000_000 + TimeVal::new().usec) / USEC_PER_TICK; + let tv = TimeVal::new(); + + let tick = (tv.sec * 1_000_000 + tv.usec) / USEC_PER_TICK; let new_buf = Tms { tms_utime: 0, diff --git a/linux-syscall/test/testtime.c b/linux-syscall/test/testtime.c new file mode 100644 index 000000000..5cfc87ed1 --- /dev/null +++ b/linux-syscall/test/testtime.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + struct timespec ts = {0, 0}; + clock_gettime(CLOCK_REALTIME, &ts); + printf("timespec: %ld sec, %ld nsec\n", ts.tv_sec, ts.tv_nsec); + + struct timeval tv; + + // the musl-libc call clock_gettime instead..qwq + gettimeofday(&tv, NULL); + printf("timeval: %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec); + + // the musl-libc call clock_gettime instead..qwq + time_t seconds; + seconds = time(NULL); + printf("time: %ld\n", seconds); + + struct tms tmp; + clock_t t = times(&tmp); + printf("times return: %ld\n", t); + + struct rusage usage; + getrusage(0, &usage); + printf("timeval getrusage user: %ld sec, %ld usec\n", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec); + printf("timeval getrusage system: %ld sec, %ld usec\n", usage.ru_stime.tv_sec, usage.ru_stime.tv_usec); + + return 0; +} \ No newline at end of file From 3e7206a6210e3450b92a477962da5e61157b4b93 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Mon, 10 Aug 2020 08:23:00 -0700 Subject: [PATCH 07/10] update some tests for non-exist files and doc in fcntl --- linux-loader/src/main.rs | 11 ++++++++--- linux-object/src/fs/fcntl.rs | 33 ++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index f1edcd6b5..02f3b0dfe 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -51,7 +51,7 @@ fn init_logger() { #[cfg(test)] mod tests { use super::*; - use std::{fs, io}; + use std::fs; /// test with cmd line async fn test(cmdline: &str) { @@ -92,6 +92,7 @@ mod tests { #[async_std::test] async fn test_create_remove_file() { + test("/bin/busybox rm testfile").await; // can't remove fs::read("../rootfs/testfile").unwrap_err(); test("/bin/busybox touch testfile").await; fs::read("../rootfs/testfile").unwrap(); @@ -103,6 +104,7 @@ mod tests { #[async_std::test] async fn test_create_remove_dir() { + test("/bin/busybox rmdir test").await; // can't remove fs::read_dir("../rootfs/test").unwrap_err(); test("/bin/busybox mkdir test").await; fs::read_dir("../rootfs/test").unwrap(); @@ -113,10 +115,12 @@ mod tests { #[async_std::test] async fn test_readfile() { test("/bin/busybox cat /etc/profile").await; + test("/bin/busybox cat /etc/profila").await; // can't open } #[async_std::test] async fn test_cp_mv() { + test("/bin/busybox cp /etc/hostnama /etc/hostname.bak").await; // can't move fs::read("../rootfs/etc/hostname.bak").unwrap_err(); test("/bin/busybox cp /etc/hostname /etc/hostname.bak").await; fs::read("../rootfs/etc/hostname.bak").unwrap(); @@ -126,6 +130,7 @@ mod tests { #[async_std::test] async fn test_link() { + test("/bin/busybox ln /etc/hostnama /etc/hostname.ln").await; // can't ln fs::read("../rootfs/etc/hostname.ln").unwrap_err(); test("/bin/busybox ln /etc/hostname /etc/hostname.ln").await; fs::read("../rootfs/etc/hostname.ln").unwrap(); @@ -143,8 +148,8 @@ mod tests { #[async_std::test] async fn test_pipe() { test("/bin/testpipe1").await; - let str = fs::read_to_string("../rootfs/testpipe.txt").unwrap(); - io::stdout().write(str.as_bytes()).unwrap(); + let string = fs::read_to_string("../rootfs/testpipe.txt").unwrap(); + assert_eq!(string, String::from("hello pipe\n")); test("/bin/busybox rm testpipe.txt").await; } diff --git a/linux-object/src/fs/fcntl.rs b/linux-object/src/fs/fcntl.rs index fce916923..6672d2de7 100644 --- a/linux-object/src/fs/fcntl.rs +++ b/linux-object/src/fs/fcntl.rs @@ -3,22 +3,37 @@ //! copy from fcntl.h (from rCore) #![allow(dead_code)] -pub const F_DUPFD: usize = 0; /* dup */ -pub const F_GETFD: usize = 1; /* get close_on_exec */ -pub const F_SETFD: usize = 2; /* set/clear close_on_exec */ -pub const F_GETFL: usize = 3; /* get file->f_flags */ -pub const F_SETFL: usize = 4; /* set file->f_flags */ -pub const F_GETLK: usize = 5; /* Get record locking info. */ -pub const F_SETLK: usize = 6; /* Set record locking info (non-blocking). */ -pub const F_SETLKW: usize = 7; /* Set record locking info (blocking). */ +/// dup +pub const F_DUPFD: usize = 0; +/// get close_on_exec +pub const F_GETFD: usize = 1; +/// set/clear close_on_exec +pub const F_SETFD: usize = 2; +/// get file->f_flags +pub const F_GETFL: usize = 3; +/// set file->f_flags +pub const F_SETFL: usize = 4; +/// Get record locking info. +pub const F_GETLK: usize = 5; +/// Set record locking info (non-blocking). +pub const F_SETLK: usize = 6; +/// Set record locking info (blocking). +pub const F_SETLKW: usize = 7; +/// SPECIFIC BASE for other const F_LINUX_SPECIFIC_BASE: usize = 1024; +/// closed during a successful execve pub const FD_CLOEXEC: usize = 1; +/// like F_DUPFD, but additionally set the close-on-exec flag pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6; +/// not blocking pub const O_NONBLOCK: usize = 0o4000; +/// move the flag bit to the end of the file before each write pub const O_APPEND: usize = 0o2000; -pub const O_CLOEXEC: usize = 0o2000000; /* set close_on_exec */ +/// set close_on_exec +pub const O_CLOEXEC: usize = 0o2000000; +/// Do not follow symbolic links. pub const AT_SYMLINK_NOFOLLOW: usize = 0x100; From b07201623b6b7fba6db9b174caae92792b96d86d Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 01:35:49 -0700 Subject: [PATCH 08/10] fix fcntl.rs --- linux-object/Cargo.toml | 1 + linux-object/src/fs/fcntl.rs | 65 ++++++++++++++++++---------------- linux-syscall/src/file/file.rs | 10 +++--- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/linux-object/Cargo.toml b/linux-object/Cargo.toml index fc45abc2c..f01a14ec0 100644 --- a/linux-object/Cargo.toml +++ b/linux-object/Cargo.toml @@ -11,6 +11,7 @@ description = "Linux kernel objects" log = "0.4" spin = "0.5" xmas-elf = "0.7" +bitflags = "1.2" hashbrown = "0.7" zircon-object = { path = "../zircon-object", features = ["elf"] } kernel-hal = { path = "../kernel-hal" } diff --git a/linux-object/src/fs/fcntl.rs b/linux-object/src/fs/fcntl.rs index 6672d2de7..75ec0ec7d 100644 --- a/linux-object/src/fs/fcntl.rs +++ b/linux-object/src/fs/fcntl.rs @@ -3,37 +3,42 @@ //! copy from fcntl.h (from rCore) #![allow(dead_code)] -/// dup -pub const F_DUPFD: usize = 0; -/// get close_on_exec -pub const F_GETFD: usize = 1; -/// set/clear close_on_exec -pub const F_SETFD: usize = 2; -/// get file->f_flags -pub const F_GETFL: usize = 3; -/// set file->f_flags -pub const F_SETFL: usize = 4; -/// Get record locking info. -pub const F_GETLK: usize = 5; -/// Set record locking info (non-blocking). -pub const F_SETLK: usize = 6; -/// Set record locking info (blocking). -pub const F_SETLKW: usize = 7; +use bitflags::bitflags; -/// SPECIFIC BASE for other const F_LINUX_SPECIFIC_BASE: usize = 1024; -/// closed during a successful execve -pub const FD_CLOEXEC: usize = 1; -/// like F_DUPFD, but additionally set the close-on-exec flag -pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6; +bitflags! { + pub struct FcntlFlags: usize { + /// dup + const F_DUPFD = 0; + /// get close_on_exec + const F_GETFD = 1; + /// set/clear close_on_exec + const F_SETFD = 2; + /// get file->f_flags + const F_GETFL = 3; + /// set file->f_flags + const F_SETFL = 4; + /// Get record locking info. + const F_GETLK = 5; + /// Set record locking info (non-blocking). + const F_SETLK = 6; + /// Set record locking info (blocking). + const F_SETLKW = 7; + /// closed during a successful execve + const FD_CLOEXEC = 1; + /// like F_DUPFD, but additionally set the close-on-exec flag + const F_DUPFD_CLOEXEC = F_LINUX_SPECIFIC_BASE + 6; + } +} -/// not blocking -pub const O_NONBLOCK: usize = 0o4000; -/// move the flag bit to the end of the file before each write -pub const O_APPEND: usize = 0o2000; -/// set close_on_exec -pub const O_CLOEXEC: usize = 0o2000000; - -/// Do not follow symbolic links. -pub const AT_SYMLINK_NOFOLLOW: usize = 0x100; +bitflags! { + pub struct FileFlags: usize { + /// not blocking + const O_NONBLOCK = 0o4000; + /// move the flag bit to the end of the file before each write + const O_APPEND = 0o2000; + /// set close_on_exec + const O_CLOEXEC = 0o2000000; + } +} diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index 70474490c..aeca8cc3e 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -363,10 +363,12 @@ impl Syscall<'_> { "utimensat: dirfd: {:?}, pathname: {:?}, times: {:?}, flags: {:#x}", dirfd, pathname, times, flags ); - let follow = match flags { - 0 => true, - AT_SYMLINK_NOFOLLOW => false, - _ => return Err(LxError::EINVAL), + let follow = if flags == 0 { + true + } else if flags == AtFlags::SYMLINK_NOFOLLOW.bits() { + false + } else { + return Err(LxError::EINVAL); }; proc.lookup_inode_at(dirfd, &pathname[..], follow)? }; From da8929e435d68b1a77dcd4954e33a241ead45861 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 01:44:15 -0700 Subject: [PATCH 09/10] some minor fix --- linux-syscall/src/file/file.rs | 6 +++--- linux-syscall/src/time.rs | 36 +++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index aeca8cc3e..d5b8fdcb2 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -347,7 +347,7 @@ impl Syscall<'_> { const UTIME_OMIT: usize = 0x3ffffffe; let proc = self.linux_process(); let mut times = if times.is_null() { - let epoch = TimeSpec::new(); + let epoch = TimeSpec::now(); [epoch, epoch] } else { let times = times.read()?; @@ -375,7 +375,7 @@ impl Syscall<'_> { let mut metadata = inode.metadata()?; if times[0].nsec != UTIME_OMIT { if times[0].nsec == UTIME_NOW { - times[0] = TimeSpec::new(); + times[0] = TimeSpec::now(); } metadata.atime = rcore_fs::vfs::Timespec { sec: times[0].sec as i64, @@ -384,7 +384,7 @@ impl Syscall<'_> { } if times[1].nsec != UTIME_OMIT { if times[1].nsec == UTIME_NOW { - times[1] = TimeSpec::new(); + times[1] = TimeSpec::now(); } metadata.mtime = rcore_fs::vfs::Timespec { sec: times[1].sec as i64, diff --git a/linux-syscall/src/time.rs b/linux-syscall/src/time.rs index 58376a44e..bc4dad3fe 100644 --- a/linux-syscall/src/time.rs +++ b/linux-syscall/src/time.rs @@ -37,7 +37,7 @@ impl Syscall<'_> { pub fn sys_clock_gettime(&self, clock: usize, mut buf: UserOutPtr) -> SysResult { info!("clock_gettime: id={:?} buf={:?}", clock, buf); // TODO: handle clock_settime - let ts = TimeSpec::new(); + let ts = TimeSpec::now(); buf.write(ts)?; info!("TimeSpec: {:?}", ts); @@ -57,7 +57,7 @@ impl Syscall<'_> { return Err(LxError::EINVAL); } - let timeval = TimeVal::new(); + let timeval = TimeVal::now(); tv.write(timeval)?; info!("TimeVal: {:?}", timeval); @@ -69,7 +69,7 @@ impl Syscall<'_> { #[cfg(target_arch = "x86_64")] pub fn sys_time(&mut self, mut time: UserOutPtr) -> SysResult { info!("time: time: {:?}", time); - let sec = TimeSpec::new().sec; + let sec = TimeSpec::now().sec; time.write(sec as u64)?; Ok(sec) } @@ -82,8 +82,8 @@ impl Syscall<'_> { info!("getrusage: who: {}, rusage: {:?}", who, rusage); let new_rusage = RUsage { - utime: TimeVal::new(), - stime: TimeVal::new(), + utime: TimeVal::now(), + stime: TimeVal::now(), }; rusage.write(new_rusage)?; Ok(0) @@ -93,7 +93,7 @@ impl Syscall<'_> { pub fn sys_times(&mut self, mut buf: UserOutPtr) -> SysResult { info!("times: buf: {:?}", buf); - let tv = TimeVal::new(); + let tv = TimeVal::now(); let tick = (tv.sec * 1_000_000 + tv.usec) / USEC_PER_TICK; @@ -113,14 +113,14 @@ impl Syscall<'_> { impl TimeVal { /// create TimeVal - pub fn new() -> TimeVal { - TimeSpec::new().into() + pub fn now() -> TimeVal { + TimeSpec::now().into() } } impl TimeSpec { /// create TimeSpec - pub fn new() -> TimeSpec { + pub fn now() -> TimeSpec { let time = timer_now(); TimeSpec { sec: time.as_secs() as usize, @@ -131,7 +131,7 @@ impl TimeSpec { /// update TimeSpec for a file inode /// TODO: more precise; update when write pub fn update(inode: &Arc) { - let now = TimeSpec::new().into(); + let now = TimeSpec::now().into(); if let Ok(mut metadata) = inode.metadata() { metadata.atime = now; metadata.mtime = now; @@ -168,13 +168,13 @@ impl Into for TimeSpec { impl Default for TimeVal { fn default() -> Self { - Self::new() + TimeVal { sec: 0, usec: 0 } } } impl Default for TimeSpec { fn default() -> Self { - Self::new() + TimeSpec { sec: 0, nsec: 0 } } } @@ -192,8 +192,12 @@ pub struct RUsage { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Tms { - tms_utime: u64, /* user time */ - tms_stime: u64, /* system time */ - tms_cutime: u64, /* user time of children */ - tms_cstime: u64, /* system time of children */ + /// user time + tms_utime: u64, + /// system time + tms_stime: u64, + /// user time of children + tms_cutime: u64, + /// system time of children + tms_cstime: u64, } From 9eaa3dccc21a72b6c7fae877ea7a4bb5d0676cb3 Mon Sep 17 00:00:00 2001 From: myub <1067852565@qq.com> Date: Tue, 11 Aug 2020 02:19:42 -0700 Subject: [PATCH 10/10] fix test return value --- linux-loader/src/main.rs | 36 +++++++++++++++++---------------- linux-syscall/test/testpipe1.c | 37 ++++++++++++++++++---------------- linux-syscall/test/testpipe2.c | 12 +++++------ linux-syscall/test/testtime.c | 6 ++++++ 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index 02f3b0dfe..0d2eb36a4 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -52,9 +52,10 @@ fn init_logger() { mod tests { use super::*; use std::fs; + use zircon_object::object::task::*; /// test with cmd line - async fn test(cmdline: &str) { + async fn test(cmdline: &str) -> i64 { kernel_hal_unix::init(); let args: Vec = cmdline.split(' ').map(|s| s.into()).collect(); @@ -62,32 +63,36 @@ mod tests { vec!["PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/x86_64-alpine-linux-musl/bin".into()]; // TODO let hostfs = HostFS::new("../rootfs"); let proc = run(args, envs, hostfs); - let proc: Arc = proc; - proc.wait_signal(Signal::PROCESS_TERMINATED).await; + let procobj: Arc = proc.clone(); + procobj.wait_signal(Signal::PROCESS_TERMINATED).await; + if let Status::Exited(code) = proc.status() { + return code; + } + -1 } // test using busybox #[async_std::test] async fn test_busybox() { - test("/bin/busybox").await; + assert_eq!(test("/bin/busybox").await, 0); } #[async_std::test] async fn test_uname() { - test("/bin/busybox uname -a").await; + assert_eq!(test("/bin/busybox uname -a").await, 0); } #[async_std::test] async fn test_date() { - test("/bin/busybox date").await; + assert_eq!(test("/bin/busybox date").await, 0); } #[async_std::test] async fn test_dir() { - test("/bin/busybox pwd").await; - test("/bin/busybox ls -a").await; - test("/bin/busybox dirname /bin/busybox").await; + assert_eq!(test("/bin/busybox pwd").await, 0); + assert_eq!(test("/bin/busybox ls -a").await, 0); + assert_eq!(test("/bin/busybox dirname /bin/busybox").await, 0); } #[async_std::test] @@ -114,8 +119,8 @@ mod tests { #[async_std::test] async fn test_readfile() { - test("/bin/busybox cat /etc/profile").await; - test("/bin/busybox cat /etc/profila").await; // can't open + assert_eq!(test("/bin/busybox cat /etc/profile").await, 0); + assert_eq!(test("/bin/busybox cat /etc/profila").await, 1); // can't open } #[async_std::test] @@ -140,21 +145,18 @@ mod tests { #[async_std::test] async fn test_env() { - test("/bin/busybox env").await; + assert_eq!(test("/bin/busybox env").await, 0); } // syscall unit test #[async_std::test] async fn test_pipe() { - test("/bin/testpipe1").await; - let string = fs::read_to_string("../rootfs/testpipe.txt").unwrap(); - assert_eq!(string, String::from("hello pipe\n")); - test("/bin/busybox rm testpipe.txt").await; + assert_eq!(test("/bin/testpipe1").await, 0); } #[async_std::test] async fn test_time() { - test("/bin/testtime").await; + assert_eq!(test("/bin/testtime").await, 0); } } diff --git a/linux-syscall/test/testpipe1.c b/linux-syscall/test/testpipe1.c index 00c207504..a60180954 100644 --- a/linux-syscall/test/testpipe1.c +++ b/linux-syscall/test/testpipe1.c @@ -4,6 +4,7 @@ #include #include #include +#include #include int main() @@ -12,31 +13,33 @@ int main() int cnt = 0; int pipefd[2]; char buf; + char received[20]; + int receivep = 0; char w[12]; char r[12]; - if (pipe(pipefd) == -1) { + if (pipe(pipefd) == -1) + { printf("pipe"); exit(-1); } - sprintf(w,"%d",pipefd[1]); - sprintf(r,"%d",pipefd[0]); + sprintf(w, "%d", pipefd[1]); + sprintf(r, "%d", pipefd[0]); pid = vfork(); - if(pid<0) + if (pid < 0) printf("error in fork!\n"); - else if(pid == 0) - { - execl("/bin/testpipe2","/bin/testpipe2",r,w,NULL); - exit(0); + else if (pid == 0) + { + execl("/bin/testpipe2", "/bin/testpipe2", r, w, NULL); + exit(0); } - else if(pid > 0) - { - close(pipefd[1]); - int fd = open("testpipe.txt", O_WRONLY | O_CREAT); - while (read(pipefd[0], &buf, 1) > 0) - write(fd, &buf, 1); - write(fd, "\n", 1); - close(pipefd[0]); - close(fd); + else if (pid > 0) + { + close(pipefd[1]); + while (read(pipefd[0], &buf, 1) > 0) + received[receivep++] = buf; + received[receivep] = 0; + assert(strcmp(received, "hello pipe") == 0); + close(pipefd[0]); } return 0; } diff --git a/linux-syscall/test/testpipe2.c b/linux-syscall/test/testpipe2.c index 1fa861a91..a93411442 100644 --- a/linux-syscall/test/testpipe2.c +++ b/linux-syscall/test/testpipe2.c @@ -5,12 +5,12 @@ #include int main(int argc, char *argv[]) -{ +{ int writefd, readfd; - sscanf(argv[2],"%d",&writefd); - sscanf(argv[1],"%d",&readfd); + sscanf(argv[2], "%d", &writefd); + sscanf(argv[1], "%d", &readfd); close(readfd); - write(writefd, "hello pipe", strlen("hello pipe")); - close(writefd); - exit(0); + write(writefd, "hello pipe", strlen("hello pipe")); + close(writefd); + exit(0); } diff --git a/linux-syscall/test/testtime.c b/linux-syscall/test/testtime.c index 5cfc87ed1..99d719e5a 100644 --- a/linux-syscall/test/testtime.c +++ b/linux-syscall/test/testtime.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -11,26 +12,31 @@ int main(int argc, char **argv) struct timespec ts = {0, 0}; clock_gettime(CLOCK_REALTIME, &ts); printf("timespec: %ld sec, %ld nsec\n", ts.tv_sec, ts.tv_nsec); + assert(ts.tv_sec != 0 && ts.tv_nsec != 0); struct timeval tv; // the musl-libc call clock_gettime instead..qwq gettimeofday(&tv, NULL); printf("timeval: %ld sec, %ld usec\n", tv.tv_sec, tv.tv_usec); + assert(tv.tv_sec != 0 && tv.tv_usec != 0); // the musl-libc call clock_gettime instead..qwq time_t seconds; seconds = time(NULL); printf("time: %ld\n", seconds); + assert(seconds != 0); struct tms tmp; clock_t t = times(&tmp); printf("times return: %ld\n", t); + assert(times != 0); struct rusage usage; getrusage(0, &usage); printf("timeval getrusage user: %ld sec, %ld usec\n", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec); printf("timeval getrusage system: %ld sec, %ld usec\n", usage.ru_stime.tv_sec, usage.ru_stime.tv_usec); + assert(usage.ru_utime.tv_sec != 0 && usage.ru_utime.tv_usec != 0); return 0; } \ No newline at end of file