diff --git a/src/console/mod.rs b/src/console/mod.rs index 42d22f97..df7a842f 100644 --- a/src/console/mod.rs +++ b/src/console/mod.rs @@ -91,7 +91,7 @@ impl Log for ConsoleLogger { let _ = write_fmt(format_args!( "[{:5}.{:06}] {}: {}\r\n", uptime.as_secs(), - uptime.as_micros(), + uptime.subsec_micros(), record .module_path() .map(|x| x.strip_prefix("moss::").unwrap_or(x)) diff --git a/src/fs/reg.rs b/src/fs/reg.rs index 71860af7..bc9ed141 100644 --- a/src/fs/reg.rs +++ b/src/fs/reg.rs @@ -12,7 +12,7 @@ use async_trait::async_trait; use core::{cmp::min, pin::Pin}; use libkernel::{ error::Result, - fs::{Inode, SeekFrom}, + fs::{Inode, OpenFlags, SeekFrom}, memory::{PAGE_SIZE, address::UA}, }; @@ -63,6 +63,17 @@ impl FileOps for RegFile { Ok(total_bytes_read) } + /// Writes at the cursor, or at the end of the file if it was opened with + /// `O_APPEND`, and advances the cursor past the data written. + async fn write(&mut self, ctx: &mut FileCtx, buf: UA, count: usize) -> Result { + if ctx.flags.contains(OpenFlags::O_APPEND) { + ctx.pos = self.inode.getattr().await?.size; + } + let bytes_written = self.writeat(buf, count, ctx.pos).await?; + ctx.pos += bytes_written as u64; + Ok(bytes_written) + } + /// Writes data from `buf` to the current file position. /// The file's cursor is advanced by the number of bytes written. async fn writeat(&mut self, mut buf: UA, mut count: usize, mut offset: u64) -> Result { diff --git a/src/fs/syscalls/chdir.rs b/src/fs/syscalls/chdir.rs index b116da5a..71bc3968 100644 --- a/src/fs/syscalls/chdir.rs +++ b/src/fs/syscalls/chdir.rs @@ -20,7 +20,7 @@ pub async fn sys_getcwd(ctx: &ProcessCtx, buf: UA, len: usize) -> Result let slice = cstr.as_bytes_with_nul(); if slice.len() > len { - return Err(KernelError::TooLarge); + return Err(KernelError::RangeError); } copy_to_user_slice(slice, buf).await?; diff --git a/usertest/src/fs.rs b/usertest/src/fs.rs index a3f62543..38969d42 100644 --- a/usertest/src/fs.rs +++ b/usertest/src/fs.rs @@ -612,3 +612,30 @@ fn test_rust_dir() { } register_test!(test_rust_dir); + +fn test_o_append() { + use std::io::{Seek, SeekFrom, Write}; + let path = "/tmp/o_append_test"; + fs::write(path, "first\n").unwrap(); + let mut file = fs::OpenOptions::new().append(true).open(path).unwrap(); + file.write_all(b"second\n").unwrap(); + // O_APPEND writes always go to the end, even after seeking elsewhere. + file.seek(SeekFrom::Start(0)).unwrap(); + file.write_all(b"third\n").unwrap(); + assert_eq!(fs::read_to_string(path).unwrap(), "first\nsecond\nthird\n"); + fs::remove_file(path).unwrap(); +} + +register_test!(test_o_append); + +fn test_getcwd_buffer_too_small() { + let mut buf = [0 as libc::c_char; 1]; + let ret = unsafe { libc::getcwd(buf.as_mut_ptr(), buf.len()) }; + assert!(ret.is_null()); + assert_eq!( + std::io::Error::last_os_error().raw_os_error(), + Some(libc::ERANGE) + ); +} + +register_test!(test_getcwd_buffer_too_small);