diff --git a/.gitattributes b/.gitattributes index 7506ffb93..d19710b5c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,6 @@ src/apps/hello_world/hello_world filter=lfs diff=lfs merge=lfs -text src/apps/fork/fork filter=lfs diff=lfs merge=lfs -text -src/appshello_c/hello filter=lfs diff=lfs merge=lfs -text +src/apps/hello_c/hello filter=lfs diff=lfs merge=lfs -text src/apps/execve/execve filter=lfs diff=lfs merge=lfs -text src/apps/execve/hello filter=lfs diff=lfs merge=lfs -text src/apps/fork_c/fork filter=lfs diff=lfs merge=lfs -text diff --git a/src/apps/scripts/run_tests.sh b/src/apps/scripts/run_tests.sh index ca45bbfdb..f3b122c4b 100755 --- a/src/apps/scripts/run_tests.sh +++ b/src/apps/scripts/run_tests.sh @@ -2,6 +2,9 @@ set -e +SCRIPT_DIR=/scripts +cd ${SCRIPT_DIR}/.. + echo "Running tests......" tests="hello_world/hello_world fork/fork execve/execve fork_c/fork signal_c/signal_test pthread/pthread_test" diff --git a/src/apps/scripts/test_cmd.sh b/src/apps/scripts/test_cmd.sh index 1083d7615..14fa12b6e 100755 --- a/src/apps/scripts/test_cmd.sh +++ b/src/apps/scripts/test_cmd.sh @@ -3,7 +3,8 @@ set -e set -x -cd scripts +SCRIPT_DIR=/scripts +cd ${SCRIPT_DIR} touch hello.txt mv hello.txt hello_world.txt diff --git a/src/services/libs/jinux-std/src/process/posix_thread/name.rs b/src/services/libs/jinux-std/src/process/posix_thread/name.rs index 22920c98c..3231f165d 100644 --- a/src/services/libs/jinux-std/src/process/posix_thread/name.rs +++ b/src/services/libs/jinux-std/src/process/posix_thread/name.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -pub const MAX_THREAD_NAME_LEN: usize = 16; +pub const MAX_THREAD_NAME_LEN: usize = 256; #[derive(Debug)] pub struct ThreadName { @@ -34,7 +34,7 @@ impl ThreadName { // if len > MAX_THREAD_NAME_LEN, truncate it. self.count = MAX_THREAD_NAME_LEN; self.inner[..MAX_THREAD_NAME_LEN].clone_from_slice(&bytes[..MAX_THREAD_NAME_LEN]); - self.inner[MAX_THREAD_NAME_LEN] = 0; + self.inner[MAX_THREAD_NAME_LEN - 1] = 0; return Ok(()); } self.count = bytes_len; diff --git a/src/services/libs/jinux-std/src/tty/line_discipline.rs b/src/services/libs/jinux-std/src/tty/line_discipline.rs index e632e6f35..e07692099 100644 --- a/src/services/libs/jinux-std/src/tty/line_discipline.rs +++ b/src/services/libs/jinux-std/src/tty/line_discipline.rs @@ -16,13 +16,13 @@ const BUFFER_CAPACITY: usize = 4096; pub struct LineDiscipline { /// current line - current_line: CurrentLine, + current_line: RwLock, /// The read buffer read_buffer: Mutex>, /// The foreground process group - foreground: Option, + foreground: RwLock>, /// termios - termios: KernelTermios, + termios: RwLock, /// wait until self is readable read_wait_queue: WaitQueue, } @@ -67,59 +67,62 @@ impl LineDiscipline { /// create a new line discipline pub fn new() -> Self { Self { - current_line: CurrentLine::new(), + current_line: RwLock::new(CurrentLine::new()), read_buffer: Mutex::new(ConstGenericRingBuffer::new()), - foreground: None, - termios: KernelTermios::default(), + foreground: RwLock::new(None), + termios: RwLock::new(KernelTermios::default()), read_wait_queue: WaitQueue::new(), } } /// push char to line discipline. This function should be called in input interrupt handler. - pub fn push_char(&mut self, mut item: u8) { - if self.termios.contains_icrnl() { + pub fn push_char(&self, mut item: u8) { + let termios = self.termios.read(); + if termios.contains_icrnl() { if item == b'\r' { item = b'\n' } } - if self.termios.is_canonical_mode() { - if item == *self.termios.get_special_char(CC_C_CHAR::VINTR) { + if termios.is_canonical_mode() { + if item == *termios.get_special_char(CC_C_CHAR::VINTR) { // type Ctrl + C, signal SIGINT - if self.termios.contains_isig() { - if let Some(fg) = self.foreground { + if termios.contains_isig() { + if let Some(fg) = *self.foreground.read() { let kernel_signal = KernelSignal::new(SIGINT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); } } - } else if item == *self.termios.get_special_char(CC_C_CHAR::VQUIT) { + } else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) { // type Ctrl + \, signal SIGQUIT - if self.termios.contains_isig() { - if let Some(fg) = self.foreground { + if termios.contains_isig() { + if let Some(fg) = *self.foreground.read() { let kernel_signal = KernelSignal::new(SIGQUIT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); } } - } else if item == *self.termios.get_special_char(CC_C_CHAR::VKILL) { + } else if item == *termios.get_special_char(CC_C_CHAR::VKILL) { // erase current line - self.current_line.drain(); - } else if item == *self.termios.get_special_char(CC_C_CHAR::VERASE) { + self.current_line.write().drain(); + } else if item == *termios.get_special_char(CC_C_CHAR::VERASE) { // type backspace - if !self.current_line.is_empty() { - self.current_line.backspace(); + let mut current_line = self.current_line.write(); + if !current_line.is_empty() { + current_line.backspace(); } } else if meet_new_line(item, &self.get_termios()) { // a new line was met. We currently add the item to buffer. // when we read content, the item should be skipped if it's EOF. - self.current_line.push_char(item); - let current_line_chars = self.current_line.drain(); + let mut current_line = self.current_line.write(); + current_line.push_char(item); + let current_line_chars = current_line.drain(); for char in current_line_chars { self.read_buffer.lock().push(char); } } else if item >= 0x20 && item < 0x7f { // printable character - self.current_line.push_char(item); + self.current_line.write().push_char(item); } } else { // raw mode @@ -127,7 +130,7 @@ impl LineDiscipline { // debug!("push char: {}", char::from(item)) } - if self.termios.contain_echo() { + if termios.contain_echo() { self.output_char(item); } @@ -147,13 +150,14 @@ impl LineDiscipline { let ch = char::from(item); print!("{}", ch); } - if item == *self.termios.get_special_char(CC_C_CHAR::VERASE) { + let termios = self.termios.read(); + if item == *termios.get_special_char(CC_C_CHAR::VERASE) { // write a space to overwrite current character let bytes: [u8; 3] = [b'\x08', b' ', b'\x08']; let backspace = core::str::from_utf8(&bytes).unwrap(); print!("{}", backspace); } - if self.termios.contains_echo_ctl() { + if termios.contains_echo_ctl() { // The unprintable chars between 1-31 are mapped to ctrl characters between 65-95. // e.g., 0x3 is mapped to 0x43, which is C. So, we will print ^C when 0x3 is met. if 0 < item && item < 0x20 { @@ -165,9 +169,11 @@ impl LineDiscipline { } /// read all bytes buffered to dst, return the actual read length. - pub fn read(&mut self, dst: &mut [u8]) -> Result { - let vmin = *self.termios.get_special_char(CC_C_CHAR::VMIN); - let vtime = *self.termios.get_special_char(CC_C_CHAR::VTIME); + pub fn read(&self, dst: &mut [u8]) -> Result { + let termios = self.termios.read(); + let vmin = *termios.get_special_char(CC_C_CHAR::VMIN); + let vtime = *termios.get_special_char(CC_C_CHAR::VTIME); + drop(termios); let read_len: usize = self.read_wait_queue.wait_until(|| { // if current process does not belong to foreground process group, // block until current process become foreground. @@ -216,10 +222,10 @@ impl LineDiscipline { let mut read_len = 0; for i in 0..max_read_len { if let Some(next_char) = buffer.dequeue() { - if self.termios.is_canonical_mode() { + if self.termios.read().is_canonical_mode() { // canonical mode, read until meet new line - if meet_new_line(next_char, self.get_termios()) { - if !should_not_be_read(next_char, self.get_termios()) { + if meet_new_line(next_char, &self.termios.read()) { + if !should_not_be_read(next_char, &self.termios.read()) { dst[i] = next_char; read_len += 1; } @@ -261,7 +267,7 @@ impl LineDiscipline { /// whether the current process belongs to foreground process group fn current_belongs_to_foreground(&self) -> bool { let current = current!(); - if let Some(fg_pgid) = self.foreground { + if let Some(fg_pgid) = *self.foreground.read() { if let Some(process_group) = process_table::pgid_to_process_group(fg_pgid) { if process_group.contains_process(current.pid()) { return true; @@ -273,8 +279,8 @@ impl LineDiscipline { } /// set foreground process group - pub fn set_fg(&mut self, fg_pgid: Pgid) { - self.foreground = Some(fg_pgid); + pub fn set_fg(&self, fg_pgid: Pgid) { + *self.foreground.write() = Some(fg_pgid); // Some background processes may be waiting on the wait queue, when set_fg, the background processes may be able to read. if self.is_readable() { self.read_wait_queue.wake_all(); @@ -282,8 +288,8 @@ impl LineDiscipline { } /// get foreground process group id - pub fn get_fg(&self) -> Option<&Pgid> { - self.foreground.as_ref() + pub fn get_fg(&self) -> Option { + *self.foreground.read() } /// whether there is buffered data @@ -291,12 +297,12 @@ impl LineDiscipline { self.read_buffer.lock().len() == 0 } - pub fn get_termios(&self) -> &KernelTermios { - &self.termios + pub fn get_termios(&self) -> KernelTermios { + *self.termios.read() } - pub fn set_termios(&mut self, termios: KernelTermios) { - self.termios = termios; + pub fn set_termios(&self, termios: KernelTermios) { + *self.termios.write() = termios; } } diff --git a/src/services/libs/jinux-std/src/tty/mod.rs b/src/services/libs/jinux-std/src/tty/mod.rs index 0f9b47893..392dac285 100644 --- a/src/services/libs/jinux-std/src/tty/mod.rs +++ b/src/services/libs/jinux-std/src/tty/mod.rs @@ -1,5 +1,6 @@ use self::line_discipline::LineDiscipline; use crate::driver::tty::TtyDriver; +use crate::fs::utils::{InodeMode, InodeType, Metadata}; use crate::fs::{ file_handle::File, utils::{IoEvents, IoctlCmd}, @@ -22,7 +23,7 @@ pub struct Tty { /// tty_name name: CString, /// line discipline - ldisc: Mutex, + ldisc: LineDiscipline, /// driver driver: Mutex>, } @@ -31,14 +32,14 @@ impl Tty { pub fn new(name: CString) -> Self { Tty { name, - ldisc: Mutex::new(LineDiscipline::new()), + ldisc: LineDiscipline::new(), driver: Mutex::new(Weak::new()), } } /// Set foreground process group pub fn set_fg(&self, pgid: Pgid) { - self.ldisc.lock().set_fg(pgid); + self.ldisc.set_fg(pgid); } pub fn set_driver(&self, driver: Weak) { @@ -48,23 +49,22 @@ impl Tty { /// Wake up foreground process group that wait on IO events. /// This function should be called when the interrupt handler of IO events is called. fn wake_fg_proc_grp(&self) { - let ldisc = self.ldisc.lock(); - if let Some(fg_pgid) = ldisc.get_fg() { - if let Some(fg_proc_grp) = process_table::pgid_to_process_group(*fg_pgid) { + if let Some(fg_pgid) = self.ldisc.get_fg() { + if let Some(fg_proc_grp) = process_table::pgid_to_process_group(fg_pgid) { fg_proc_grp.wake_all_polling_procs(); } } } pub fn receive_char(&self, item: u8) { - self.ldisc.lock().push_char(item); + self.ldisc.push_char(item); self.wake_fg_proc_grp(); } } impl File for Tty { fn read(&self, buf: &mut [u8]) -> Result { - self.ldisc.lock().read(buf) + self.ldisc.read(buf) } fn write(&self, buf: &[u8]) -> Result { @@ -77,28 +77,26 @@ impl File for Tty { } fn poll(&self) -> IoEvents { - self.ldisc.lock().poll() + self.ldisc.poll() } fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { match cmd { IoctlCmd::TCGETS => { // Get terminal attributes - let ldist_lock = self.ldisc.lock(); - let termios = ldist_lock.get_termios(); + let termios = self.ldisc.get_termios(); debug!("get termios = {:?}", termios); - write_val_to_user(arg, termios)?; + write_val_to_user(arg, &termios)?; Ok(0) } IoctlCmd::TIOCGPGRP => { // FIXME: Get the process group ID of the foreground process group on this terminal. - let ldist_lock = self.ldisc.lock(); - let fg_pgid = ldist_lock.get_fg(); + let fg_pgid = self.ldisc.get_fg(); match fg_pgid { None => return_errno_with_message!(Errno::ENOENT, "No fg process group"), Some(fg_pgid) => { debug!("fg_pgid = {}", fg_pgid); - write_val_to_user(arg, fg_pgid)?; + write_val_to_user(arg, &fg_pgid)?; Ok(0) } } @@ -106,16 +104,14 @@ impl File for Tty { IoctlCmd::TIOCSPGRP => { // Set the process group id of fg progress group let pgid = read_val_from_user::(arg)?; - let mut ldist_lock = self.ldisc.lock(); - ldist_lock.set_fg(pgid); + self.ldisc.set_fg(pgid); Ok(0) } IoctlCmd::TCSETS => { // Set terminal attributes let termios = read_val_from_user(arg)?; debug!("set termios = {:?}", termios); - let mut ldist_lock = self.ldisc.lock(); - ldist_lock.set_termios(termios); + self.ldisc.set_termios(termios); Ok(0) } IoctlCmd::TIOCGWINSZ => { @@ -125,6 +121,25 @@ impl File for Tty { _ => todo!(), } } + + fn metadata(&self) -> Metadata { + Metadata { + dev: 0, + ino: 0, + size: 0, + blk_size: 1024, + blocks: 0, + atime: Default::default(), + mtime: Default::default(), + ctime: Default::default(), + type_: InodeType::CharDevice, + mode: InodeMode::from_bits_truncate(0o666), + nlinks: 1, + uid: 0, + gid: 0, + rdev: 0, + } + } } /// FIXME: should we maintain a static console?