实现pty,附带测试程序 (#685)

* 实现pty,附带测试程序

* fmt ** clippy

* 将file层的锁粒度缩小,从而不使用no_preempt。更改pipe在sleep部分的bug

* 修复拼写错误
This commit is contained in:
GnoCiYeH 2024-04-05 00:21:55 +08:00 committed by GitHub
parent b8ed38251d
commit dfe53cf087
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 1691 additions and 384 deletions

View File

@ -18,6 +18,12 @@ impl Major {
/// /dev/fb* framebuffers /// /dev/fb* framebuffers
pub const FB_MAJOR: Self = Self::new(29); pub const FB_MAJOR: Self = Self::new(29);
/// Pty
pub const UNIX98_PTY_MASTER_MAJOR: Self = Self::new(128);
pub const UNIX98_PTY_MAJOR_COUNT: Self = Self::new(8);
pub const UNIX98_PTY_SLAVE_MAJOR: Self =
Self::new(Self::UNIX98_PTY_MASTER_MAJOR.0 + Self::UNIX98_PTY_MAJOR_COUNT.0);
pub const fn new(x: u32) -> Self { pub const fn new(x: u32) -> Self {
Major(x) Major(x)
} }

View File

@ -6,6 +6,7 @@ use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{ use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::{libs::spinlock::SpinLock, time::TimeSpec}; use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{ use alloc::{
string::String, string::String,
@ -76,11 +77,15 @@ impl IndexNode for LockedAhciInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }
@ -114,13 +119,13 @@ impl IndexNode for LockedAhciInode {
offset: usize, // lba地址 offset: usize, // lba地址
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
} }
if let FilePrivateData::Unused = data { if let FilePrivateData::Unused = *data {
return self.0.lock().disk.read_at_bytes(offset, len, buf); return self.0.lock().disk.read_at_bytes(offset, len, buf);
} }
@ -133,13 +138,13 @@ impl IndexNode for LockedAhciInode {
offset: usize, // lba地址 offset: usize, // lba地址
len: usize, len: usize,
buf: &[u8], buf: &[u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
} }
if let FilePrivateData::Unused = data { if let FilePrivateData::Unused = *data {
return self.0.lock().disk.write_at_bytes(offset, len, buf); return self.0.lock().disk.write_at_bytes(offset, len, buf);
} }

View File

@ -36,7 +36,7 @@ use crate::{
}, },
libs::{ libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard}, rwlock::{RwLockReadGuard, RwLockWriteGuard},
spinlock::SpinLock, spinlock::{SpinLock, SpinLockGuard},
}, },
time::TimeSpec, time::TimeSpec,
}; };
@ -587,7 +587,7 @@ impl DeviceINode for Ps2MouseDevice {
impl IndexNode for Ps2MouseDevice { impl IndexNode for Ps2MouseDevice {
fn open( fn open(
&self, &self,
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
_mode: &crate::filesystem::vfs::file::FileMode, _mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
let mut guard = self.inner.lock_irqsave(); let mut guard = self.inner.lock_irqsave();
@ -595,7 +595,7 @@ impl IndexNode for Ps2MouseDevice {
Ok(()) Ok(())
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let mut guard = self.inner.lock_irqsave(); let mut guard = self.inner.lock_irqsave();
guard.buf.clear(); guard.buf.clear();
Ok(()) Ok(())
@ -606,7 +606,7 @@ impl IndexNode for Ps2MouseDevice {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let mut guard = self.inner.lock_irqsave(); let mut guard = self.inner.lock_irqsave();
@ -625,7 +625,7 @@ impl IndexNode for Ps2MouseDevice {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
} }

View File

@ -27,7 +27,11 @@ use crate::{
}, },
}, },
init::initcall::INITCALL_DEVICE, init::initcall::INITCALL_DEVICE,
libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock}, libs::{
keyboard_parser::TypeOneFSM,
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
time::TimeSpec, time::TimeSpec,
}; };
use system_error::SystemError; use system_error::SystemError;
@ -115,7 +119,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return Err(SystemError::ENOSYS); return Err(SystemError::ENOSYS);
} }
@ -125,16 +129,20 @@ impl IndexNode for LockedPS2KeyBoardInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return Err(SystemError::ENOSYS); return Err(SystemError::ENOSYS);
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }

View File

@ -5,6 +5,7 @@ use kdepends::thingbuf::StaticThingBuf;
use crate::{ use crate::{
arch::sched::sched, arch::sched::sched,
driver::tty::virtual_terminal::virtual_console::CURRENT_VCNUM,
process::{ process::{
kthread::{KernelThreadClosure, KernelThreadMechanism}, kthread::{KernelThreadClosure, KernelThreadMechanism},
ProcessControlBlock, ProcessFlags, ProcessControlBlock, ProcessFlags,
@ -54,7 +55,12 @@ fn tty_refresh_thread() -> i32 {
*item = KEYBUF.pop().unwrap(); *item = KEYBUF.pop().unwrap();
} }
let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue); if CURRENT_VCNUM.load(core::sync::atomic::Ordering::SeqCst) != -1 {
let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
} else {
// 这里由于stdio未初始化所以无法找到port
// TODO: 考虑改用双端队列,能够将丢失的输入插回
}
} }
} }

View File

@ -2,6 +2,7 @@ use alloc::vec::Vec;
pub mod console; pub mod console;
pub mod kthread; pub mod kthread;
pub mod pty;
mod sysfs; mod sysfs;
pub mod termios; pub mod termios;
pub mod tty_core; pub mod tty_core;

View File

@ -0,0 +1,288 @@
use alloc::{
string::{String, ToString},
sync::Arc,
};
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::{
driver::base::device::{
device_number::{DeviceNumber, Major},
device_register, IdTable,
},
filesystem::devfs::devfs_register,
init::initcall::INITCALL_DEVICE,
libs::lazy_init::Lazy,
mm::VirtAddr,
syscall::user_access::{UserBufferReader, UserBufferWriter},
};
use self::unix98pty::{Unix98PtyDriverInner, NR_UNIX98_PTY_MAX};
use super::{
termios::{ControlMode, InputMode, LocalMode, OutputMode, TTY_STD_TERMIOS},
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyPacketStatus},
tty_device::{TtyDevice, TtyType},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TTY_DRIVERS},
tty_port::{DefaultTtyPort, TtyPort},
};
pub mod unix98pty;
static PTM_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
static PTS_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
pub(super) fn ptm_driver() -> Arc<TtyDriver> {
PTM_DRIVER.ensure();
PTM_DRIVER.get().clone()
}
pub(super) fn pts_driver() -> Arc<TtyDriver> {
PTS_DRIVER.ensure();
PTS_DRIVER.get().clone()
}
// lazy_static! {
// pub static ref PTM_DRIVER: Arc<TtyDriver> = {
// let mut ptm_driver = TtyDriver::new(
// NR_UNIX98_PTY_MAX,
// "ptm",
// 0,
// Major::UNIX98_PTY_MASTER_MAJOR,
// 0,
// TtyDriverType::Pty,
// *TTY_STD_TERMIOS,
// Arc::new(Unix98PtyDriverInner::new()),
// );
// ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
// let term = ptm_driver.init_termios_mut();
// term.input_mode = InputMode::empty();
// term.output_mode = OutputMode::empty();
// term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
// term.local_mode = LocalMode::empty();
// term.input_speed = 38400;
// term.output_speed = 38400;
// TtyDriverManager::tty_register_driver(ptm_driver).unwrap()
// };
// pub static ref PTS_DRIVER: Arc<TtyDriver> = {
// let mut pts_driver = TtyDriver::new(
// NR_UNIX98_PTY_MAX,
// "pts",
// 0,
// Major::UNIX98_PTY_SLAVE_MAJOR,
// 0,
// TtyDriverType::Pty,
// *TTY_STD_TERMIOS,
// Arc::new(Unix98PtyDriverInner::new()),
// );
// pts_driver.set_subtype(TtyDriverSubType::PtySlave);
// let term = pts_driver.init_termios_mut();
// term.input_mode = InputMode::empty();
// term.output_mode = OutputMode::empty();
// term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
// term.local_mode = LocalMode::empty();
// term.input_speed = 38400;
// term.output_speed = 38400;
// TtyDriverManager::tty_register_driver(pts_driver).unwrap()
// };
// }
pub struct PtyCommon;
impl PtyCommon {
pub fn pty_common_install(
driver: Arc<TtyDriver>,
tty: Arc<TtyCore>,
legacy: bool,
) -> Result<(), SystemError> {
let core = tty.core();
let other_driver = driver.other_pty_driver().unwrap();
let other_tty = TtyCore::new(other_driver.clone(), core.index());
other_driver.add_tty(other_tty.clone());
let port0: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
let port1: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
let o_core = other_tty.core();
if legacy {
core.init_termios();
o_core.init_termios();
driver
.other_pty_driver()
.unwrap()
.ttys()
.insert(core.index(), other_tty.clone());
driver.ttys().insert(core.index(), tty.clone());
} else {
*core.termios_write() = driver.init_termios();
*o_core.termios_write() = driver.other_pty_driver().unwrap().init_termios();
}
core.set_link(Arc::downgrade(&other_tty));
o_core.set_link(Arc::downgrade(&tty));
port0.setup_internal_tty(Arc::downgrade(&other_tty));
port1.setup_internal_tty(Arc::downgrade(&tty));
other_tty.set_port(port0);
tty.set_port(port1);
core.add_count();
o_core.add_count();
// 将pts加入pts Driver管理队列
PTS_DRIVER.ttys().insert(core.index(), other_tty);
Ok(())
}
pub fn pty_common_open(core: &TtyCoreData) -> Result<(), SystemError> {
if let Some(link) = core.link() {
let link_core = link.core();
if core.flags().contains(TtyFlag::OTHER_CLOSED) {
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
if link_core.flags().contains(TtyFlag::PTY_LOCK) {
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
if core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave
&& link_core.count() != 1
{
// 只能有一个master如果当前为slave则link的count必须为1
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
core.flags_write().remove(TtyFlag::IO_ERROR);
link_core.flags_write().remove(TtyFlag::OTHER_CLOSED);
core.flags_write().insert(TtyFlag::THROTTLED);
return Ok(());
}
return Err(SystemError::ENODEV);
}
pub fn pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let user_reader =
UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
if *user_reader.read_one_from_user::<i32>(0)? != 0 {
tty.flags_write().insert(TtyFlag::PTY_LOCK);
} else {
tty.flags_write().remove(TtyFlag::PTY_LOCK);
}
Ok(())
}
pub fn pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let mut user_writer =
UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
user_writer.copy_one_to_user(&tty.flags().contains(TtyFlag::PTY_LOCK), 0)?;
Ok(())
}
pub fn pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let user_reader =
UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
let mut ctrl = tty.contorl_info_irqsave();
if *user_reader.read_one_from_user::<i32>(0)? != 0 {
if !ctrl.packet {
tty.link().unwrap().core().contorl_info_irqsave().pktstatus =
TtyPacketStatus::empty();
ctrl.packet = true;
}
} else {
ctrl.packet = false;
}
Ok(())
}
pub fn pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let mut user_writer =
UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
user_writer.copy_one_to_user(&tty.contorl_info_irqsave().packet, 0)?;
Ok(())
}
pub fn unix98pty_init() -> Result<(), SystemError> {
let ptm_driver = ptm_driver();
let pts_driver = pts_driver();
ptm_driver.set_other_pty_driver(Arc::downgrade(&pts_driver));
pts_driver.set_other_pty_driver(Arc::downgrade(&ptm_driver));
let idt = IdTable::new(
String::from("ptmx"),
Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 2)),
);
let ptmx_dev = TtyDevice::new(
"ptmx".to_string(),
idt.clone(),
TtyType::Pty(super::tty_device::PtyType::Ptm),
);
ptmx_dev.inner_write().metadata_mut().raw_dev = idt.device_number();
device_register(ptmx_dev.clone())?;
devfs_register("ptmx", ptmx_dev)?;
TTY_DRIVERS.lock().push(ptm_driver);
TTY_DRIVERS.lock().push(pts_driver);
Ok(())
}
}
#[unified_init(INITCALL_DEVICE)]
#[inline(never)]
pub fn pty_init() -> Result<(), SystemError> {
let mut ptm_driver = TtyDriver::new(
NR_UNIX98_PTY_MAX,
"ptm",
0,
Major::UNIX98_PTY_MASTER_MAJOR,
0,
TtyDriverType::Pty,
*TTY_STD_TERMIOS,
Arc::new(Unix98PtyDriverInner::new()),
);
ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
let term = ptm_driver.init_termios_mut();
term.input_mode = InputMode::empty();
term.output_mode = OutputMode::empty();
term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
term.local_mode = LocalMode::empty();
term.input_speed = 38400;
term.output_speed = 38400;
PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap());
let mut pts_driver = TtyDriver::new(
NR_UNIX98_PTY_MAX,
"pts",
0,
Major::UNIX98_PTY_SLAVE_MAJOR,
0,
TtyDriverType::Pty,
*TTY_STD_TERMIOS,
Arc::new(Unix98PtyDriverInner::new()),
);
pts_driver.set_subtype(TtyDriverSubType::PtySlave);
let term = pts_driver.init_termios_mut();
term.input_mode = InputMode::empty();
term.output_mode = OutputMode::empty();
term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
term.local_mode = LocalMode::empty();
term.input_speed = 38400;
term.output_speed = 38400;
PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap());
return PtyCommon::unix98pty_init();
}

View File

@ -0,0 +1,222 @@
use alloc::{string::ToString, sync::Arc};
use system_error::SystemError;
use crate::{
driver::tty::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
tty_device::TtyFilePrivateData,
tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
},
filesystem::{
devpts::DevPtsFs,
vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
VFS_MAX_FOLLOW_SYMLINK_TIMES,
},
},
libs::spinlock::SpinLockGuard,
mm::VirtAddr,
net::event_poll::EPollEventType,
syscall::user_access::UserBufferWriter,
};
use super::{ptm_driver, pts_driver, PtyCommon};
pub const NR_UNIX98_PTY_MAX: u32 = 128;
#[derive(Debug)]
pub struct Unix98PtyDriverInner;
impl Unix98PtyDriverInner {
pub fn new() -> Self {
Self
}
}
impl TtyOperation for Unix98PtyDriverInner {
fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
PtyCommon::pty_common_install(driver, tty, false)
}
fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
PtyCommon::pty_common_open(tty)
}
fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
let to = tty.checked_link()?;
if nr == 0 || tty.flow_irqsave().stopped {
return Ok(0);
}
to.core().port().unwrap().receive_buf(buf, &[], nr)
}
fn write_room(&self, tty: &TtyCoreData) -> usize {
// TODO 暂时
if tty.flow_irqsave().stopped {
return 0;
}
8192
}
fn flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
let to = tty.checked_link()?;
let mut ctrl = to.core().contorl_info_irqsave();
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_FLUSHWRITE);
to.core().read_wq().wakeup_all();
Ok(())
}
fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
return Err(SystemError::ENOSYS);
}
match cmd {
TtyIoctlCmd::TIOCSPTLCK => {
return PtyCommon::pty_set_lock(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPTLCK => {
return PtyCommon::pty_get_lock(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCPKT => {
return PtyCommon::pty_set_packet_mode(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPKT => {
return PtyCommon::pty_get_packet_mode(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPTN => {
let mut user_writer =
UserBufferWriter::new(arg as *mut u32, core::mem::size_of::<u32>(), true)?;
return user_writer.copy_one_to_user(&(core.index() as u32), 0);
}
_ => {
return Err(SystemError::ENOIOCTLCMD);
}
}
}
fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
todo!()
}
fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
let link = core.checked_link()?;
let mut ctrl = core.contorl_info_irqsave();
ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_STOP);
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_START);
link.core()
.read_wq()
.wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
Ok(())
}
fn stop(&self, core: &TtyCoreData) -> Result<(), SystemError> {
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
let link = core.checked_link()?;
let mut ctrl = core.contorl_info_irqsave();
ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_START);
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_STOP);
link.core()
.read_wq()
.wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
Ok(())
}
fn flush_chars(&self, _tty: &TtyCoreData) {
// 不做处理
}
fn lookup(
&self,
index: usize,
priv_data: TtyDriverPrivateData,
) -> Result<Arc<TtyCore>, SystemError> {
if let TtyDriverPrivateData::Pty(false) = priv_data {
return pts_driver()
.ttys()
.get(&index)
.cloned()
.ok_or(SystemError::ENODEV);
}
return Err(SystemError::ENOSYS);
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
let driver = tty.core().driver();
driver.ttys().remove(&tty.core().index());
if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
let pts_root_inode =
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let _ = pts_root_inode.unlink(&tty.core().index().to_string());
}
Ok(())
}
}
pub fn ptmx_open(
mut data: SpinLockGuard<FilePrivateData>,
mode: &FileMode,
) -> Result<(), SystemError> {
let pts_root_inode =
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let fs = pts_root_inode
.fs()
.as_any_ref()
.downcast_ref::<MountFS>()
.unwrap()
.inner_filesystem();
let fsinfo = fs.as_any_ref().downcast_ref::<DevPtsFs>().unwrap();
let index = fsinfo.alloc_index()?;
let tty = TtyDriver::init_tty_device(ptm_driver(), index)?;
// 设置privdata
*data = FilePrivateData::Tty(TtyFilePrivateData {
tty: tty.clone(),
mode: *mode,
});
let core = tty.core();
core.flags_write().insert(TtyFlag::PTY_LOCK);
let _ = pts_root_inode.create(
&index.to_string(),
FileType::CharDevice,
ModeType::from_bits_truncate(0x666),
)?;
ptm_driver().driver_funcs().open(core)?;
Ok(())
}

View File

@ -1,9 +1,14 @@
use core::{ use core::{
fmt::Debug, fmt::Debug,
sync::atomic::{AtomicBool, AtomicUsize}, sync::atomic::{AtomicBool, AtomicUsize, Ordering},
}; };
use alloc::{collections::LinkedList, string::String, sync::Arc, vec::Vec}; use alloc::{
collections::LinkedList,
string::String,
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
@ -55,7 +60,7 @@ impl TtyCore {
ctrl: SpinLock::new(TtyContorlInfo::default()), ctrl: SpinLock::new(TtyContorlInfo::default()),
closing: AtomicBool::new(false), closing: AtomicBool::new(false),
flow: SpinLock::new(TtyFlowState::default()), flow: SpinLock::new(TtyFlowState::default()),
link: None, link: RwLock::default(),
epitems: SpinLock::new(LinkedList::new()), epitems: SpinLock::new(LinkedList::new()),
}; };
@ -138,7 +143,7 @@ impl TtyCore {
self.core() self.core()
.write_wq .write_wq
.wakeup(EPollEventType::EPOLLOUT.bits() as u64); .wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
} }
pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> { pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
@ -252,7 +257,7 @@ pub struct TtyContorlInfo {
pub pgid: Option<Pid>, pub pgid: Option<Pid>,
/// packet模式下使用目前未用到 /// packet模式下使用目前未用到
pub pktstatus: u8, pub pktstatus: TtyPacketStatus,
pub packet: bool, pub packet: bool,
} }
@ -296,7 +301,7 @@ pub struct TtyCoreData {
/// 流控状态 /// 流控状态
flow: SpinLock<TtyFlowState>, flow: SpinLock<TtyFlowState>,
/// 链接tty /// 链接tty
link: Option<Arc<TtyCore>>, link: RwLock<Weak<TtyCore>>,
/// epitems /// epitems
epitems: SpinLock<LinkedList<Arc<EPollItem>>>, epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
} }
@ -332,6 +337,11 @@ impl TtyCoreData {
*self.flags.read_irqsave() *self.flags.read_irqsave()
} }
#[inline]
pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
self.flags.write_irqsave()
}
#[inline] #[inline]
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> { pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
self.termios.read_irqsave() self.termios.read_irqsave()
@ -348,6 +358,11 @@ impl TtyCoreData {
*termios_guard = termios; *termios_guard = termios;
} }
#[inline]
pub fn count(&self) -> usize {
self.count.load(Ordering::SeqCst)
}
#[inline] #[inline]
pub fn add_count(&self) { pub fn add_count(&self) {
self.count self.count
@ -391,7 +406,36 @@ impl TtyCoreData {
#[inline] #[inline]
pub fn link(&self) -> Option<Arc<TtyCore>> { pub fn link(&self) -> Option<Arc<TtyCore>> {
self.link.clone() self.link.read().upgrade()
}
pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> {
if let Some(link) = self.link() {
return Ok(link);
}
return Err(SystemError::ENODEV);
}
pub fn set_link(&self, link: Weak<TtyCore>) {
*self.link.write() = link;
}
pub fn init_termios(&self) {
let tty_index = self.index();
let driver = self.driver();
// 初始化termios
if !driver
.flags()
.contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS)
{
// 先查看是否有已经保存的termios
if let Some(t) = driver.saved_termios().get(tty_index) {
let mut termios = *t;
termios.line = driver.init_termios().line;
self.set_termios(termios);
}
}
// TODO:设置termios波特率
} }
#[inline] #[inline]
@ -463,6 +507,10 @@ impl TtyOperation for TtyCore {
.driver_funcs() .driver_funcs()
.set_termios(tty, old_termios); .set_termios(tty, old_termios);
} }
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
self.core().tty_driver.driver_funcs().close(tty)
}
} }
bitflags! { bitflags! {
@ -492,6 +540,19 @@ bitflags! {
/// 终端线路驱动程序已停止 /// 终端线路驱动程序已停止
const LDISC_HALTED = 1 << 22; const LDISC_HALTED = 1 << 22;
} }
#[derive(Default)]
pub struct TtyPacketStatus: u8 {
/* Used for packet mode */
const TIOCPKT_DATA = 0;
const TIOCPKT_FLUSHREAD = 1;
const TIOCPKT_FLUSHWRITE = 2;
const TIOCPKT_STOP = 4;
const TIOCPKT_START = 8;
const TIOCPKT_NOSTOP = 16;
const TIOCPKT_DOSTOP = 32;
const TIOCPKT_IOCTL = 64;
}
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -614,4 +675,12 @@ impl TtyIoctlCmd {
pub const TIOCCBRK: u32 = 0x5428; pub const TIOCCBRK: u32 = 0x5428;
/// Return the session ID of FD /// Return the session ID of FD
pub const TIOCGSID: u32 = 0x5429; pub const TIOCGSID: u32 = 0x5429;
/// 设置ptl锁标记
pub const TIOCSPTLCK: u32 = 0x40045431;
/// 获取ptl锁标记
pub const TIOCGPTLCK: u32 = 0x80045439;
/// 获取packet标记
pub const TIOCGPKT: u32 = 0x80045438;
/// 获取pts index
pub const TIOCGPTN: u32 = 0x80045430;
} }

View File

@ -29,7 +29,10 @@ use crate::{
vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata}, vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
}, },
init::initcall::INITCALL_DEVICE, init::initcall::INITCALL_DEVICE,
libs::rwlock::RwLock, libs::{
rwlock::{RwLock, RwLockWriteGuard},
spinlock::SpinLockGuard,
},
mm::VirtAddr, mm::VirtAddr,
net::event_poll::{EPollItem, EventPoll}, net::event_poll::{EPollItem, EventPoll},
process::ProcessManager, process::ProcessManager,
@ -38,10 +41,11 @@ use crate::{
use super::{ use super::{
kthread::tty_flush_thread_init, kthread::tty_flush_thread_init,
pty::unix98pty::ptmx_open,
sysfs::sys_class_tty_instance, sysfs::sys_class_tty_instance,
termios::WindowSize, termios::WindowSize,
tty_core::{TtyCore, TtyFlag, TtyIoctlCmd}, tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation}, tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_job_control::TtyJobCtrlManager, tty_job_control::TtyJobCtrlManager,
virtual_terminal::vty_init, virtual_terminal::vty_init,
}; };
@ -72,13 +76,30 @@ impl InnerTtyDevice {
metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)), metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
} }
} }
pub fn metadata_mut(&mut self) -> &mut Metadata {
&mut self.metadata
}
}
#[derive(Debug, PartialEq)]
pub enum TtyType {
Tty,
Pty(PtyType),
}
#[derive(Debug, PartialEq)]
pub enum PtyType {
Ptm,
Pts,
} }
#[derive(Debug)] #[derive(Debug)]
#[cast_to([sync] Device)] #[cast_to([sync] Device)]
pub struct TtyDevice { pub struct TtyDevice {
name: &'static str, name: String,
id_table: IdTable, id_table: IdTable,
tty_type: TtyType,
inner: RwLock<InnerTtyDevice>, inner: RwLock<InnerTtyDevice>,
kobj_state: LockedKObjectState, kobj_state: LockedKObjectState,
/// TTY所属的文件系统 /// TTY所属的文件系统
@ -86,7 +107,7 @@ pub struct TtyDevice {
} }
impl TtyDevice { impl TtyDevice {
pub fn new(name: &'static str, id_table: IdTable) -> Arc<TtyDevice> { pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
let dev_num = id_table.device_number(); let dev_num = id_table.device_number();
let dev = TtyDevice { let dev = TtyDevice {
name, name,
@ -94,23 +115,37 @@ impl TtyDevice {
inner: RwLock::new(InnerTtyDevice::new()), inner: RwLock::new(InnerTtyDevice::new()),
kobj_state: LockedKObjectState::new(None), kobj_state: LockedKObjectState::new(None),
fs: RwLock::new(Weak::default()), fs: RwLock::new(Weak::default()),
tty_type,
}; };
dev.inner.write().metadata.raw_dev = dev_num; dev.inner.write().metadata.raw_dev = dev_num;
Arc::new(dev) Arc::new(dev)
} }
pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
self.inner.write()
}
} }
impl IndexNode for TtyDevice { impl IndexNode for TtyDevice {
fn open( fn open(
&self, &self,
data: &mut crate::filesystem::vfs::FilePrivateData, mut data: SpinLockGuard<FilePrivateData>,
mode: &crate::filesystem::vfs::file::FileMode, mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
if self.tty_type == TtyType::Pty(PtyType::Ptm) {
if let FilePrivateData::Tty(_) = &*data {
return Ok(());
}
return ptmx_open(data, mode);
}
let dev_num = self.metadata()?.raw_dev; let dev_num = self.metadata()?.raw_dev;
let tty = TtyDriver::open_tty(dev_num)?; let (index, driver) =
TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
let tty = TtyDriver::open_tty(index, driver)?;
// 设置privdata // 设置privdata
*data = FilePrivateData::Tty(TtyFilePrivateData { *data = FilePrivateData::Tty(TtyFilePrivateData {
@ -148,14 +183,16 @@ impl IndexNode for TtyDevice {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
data: &mut crate::filesystem::vfs::FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> { ) -> Result<usize, system_error::SystemError> {
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data { let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty.clone(), tty_priv.mode) (tty_priv.tty(), tty_priv.mode)
} else { } else {
return Err(SystemError::EIO); return Err(SystemError::EIO);
}; };
drop(data);
let ld = tty.ldisc(); let ld = tty.ldisc();
let mut offset = 0; let mut offset = 0;
let mut cookie = false; let mut cookie = false;
@ -188,15 +225,15 @@ impl IndexNode for TtyDevice {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
data: &mut crate::filesystem::vfs::FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> { ) -> Result<usize, system_error::SystemError> {
let mut count = len; let mut count = len;
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data { let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty.clone(), tty_priv.mode) (tty_priv.tty(), tty_priv.mode)
} else { } else {
return Err(SystemError::EIO); return Err(SystemError::EIO);
}; };
drop(data);
let ld = tty.ldisc(); let ld = tty.ldisc();
let core = tty.core(); let core = tty.core();
let mut chunk = 2048; let mut chunk = 2048;
@ -239,7 +276,7 @@ impl IndexNode for TtyDevice {
} }
fn as_any_ref(&self) -> &dyn core::any::Any { fn as_any_ref(&self) -> &dyn core::any::Any {
todo!() self
} }
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> { fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
@ -250,17 +287,30 @@ impl IndexNode for TtyDevice {
Ok(self.inner.read().metadata.clone()) Ok(self.inner.read().metadata.clone())
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
let mut guard = self.inner_write();
guard.metadata = metadata.clone();
Ok(()) Ok(())
} }
fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
tty.close(tty.clone())
}
fn resize(&self, _len: usize) -> Result<(), SystemError> { fn resize(&self, _len: usize) -> Result<(), SystemError> {
Ok(()) Ok(())
} }
fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> { fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode) (tty_priv.tty(), tty_priv.mode)
} else { } else {
return Err(SystemError::EIO); return Err(SystemError::EIO);
}; };
@ -485,8 +535,14 @@ impl CharDevice for TtyDevice {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TtyFilePrivateData { pub struct TtyFilePrivateData {
tty: Arc<TtyCore>, pub tty: Arc<TtyCore>,
mode: FileMode, pub mode: FileMode,
}
impl TtyFilePrivateData {
pub fn tty(&self) -> Arc<TtyCore> {
self.tty.clone()
}
} }
/// 初始化tty设备和console子设备 /// 初始化tty设备和console子设备
@ -494,19 +550,21 @@ pub struct TtyFilePrivateData {
#[inline(never)] #[inline(never)]
pub fn tty_init() -> Result<(), SystemError> { pub fn tty_init() -> Result<(), SystemError> {
let tty = TtyDevice::new( let tty = TtyDevice::new(
"tty0", "tty0".to_string(),
IdTable::new( IdTable::new(
String::from("tty0"), String::from("tty0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)), Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
), ),
TtyType::Tty,
); );
let console = TtyDevice::new( let console = TtyDevice::new(
"console", "console".to_string(),
IdTable::new( IdTable::new(
String::from("console"), String::from("console"),
Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
), ),
TtyType::Tty,
); );
// 注册tty设备 // 注册tty设备
@ -536,8 +594,8 @@ pub fn tty_init() -> Result<(), SystemError> {
// 将这两个设备注册到devfsTODO这里console设备应该与tty在一个设备group里面 // 将这两个设备注册到devfsTODO这里console设备应该与tty在一个设备group里面
device_register(tty.clone())?; device_register(tty.clone())?;
device_register(console.clone())?; device_register(console.clone())?;
devfs_register(tty.name, tty)?; devfs_register(&tty.name.clone(), tty)?;
devfs_register(console.name, console)?; devfs_register(&console.name.clone(), console)?;
serial_init()?; serial_init()?;

View File

@ -1,8 +1,8 @@
use core::{fmt::Debug, sync::atomic::Ordering}; use core::fmt::Debug;
use alloc::{ use alloc::{
string::{String, ToString}, string::{String, ToString},
sync::Arc, sync::{Arc, Weak},
vec::Vec, vec::Vec,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -20,38 +20,46 @@ use crate::{
}, },
tty::tty_port::TtyPortState, tty::tty_port::TtyPortState,
}, },
libs::spinlock::SpinLock, libs::{
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
}; };
use super::{ use super::{
termios::Termios, termios::Termios,
tty_core::{TtyCore, TtyCoreData}, tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager, tty_ldisc::TtyLdiscManager,
tty_port::TTY_PORTS, tty_port::{DefaultTtyPort, TtyPort},
virtual_terminal::virtual_console::CURRENT_VCNUM,
}; };
lazy_static! { lazy_static! {
static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new()); pub static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
}
pub enum TtyDriverPrivateData {
Unused,
/// true表示主设备 false表示从设备
Pty(bool),
} }
pub struct TtyDriverManager; pub struct TtyDriverManager;
impl TtyDriverManager { impl TtyDriverManager {
pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> { pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
let drivers_guard = TTY_DRIVERS.lock(); let drivers_guard = TTY_DRIVERS.lock();
for (index, driver) in drivers_guard.iter().enumerate() { for driver in drivers_guard.iter() {
let base = DeviceNumber::new(driver.major, driver.minor_start); let base = DeviceNumber::new(driver.major, driver.minor_start);
if dev_num < base || dev_num.data() > base.data() + driver.device_count { if dev_num < base || dev_num.data() > base.data() + driver.device_count {
continue; continue;
} }
return Some((index, driver.clone())); return Some(((dev_num.data() - base.data()) as usize, driver.clone()));
} }
None None
} }
/// ## 注册驱动 /// ## 注册驱动
pub fn tty_register_driver(mut driver: TtyDriver) -> Result<(), SystemError> { pub fn tty_register_driver(mut driver: TtyDriver) -> Result<Arc<TtyDriver>, SystemError> {
// 查看是否注册设备号 // 查看是否注册设备号
if driver.major == Major::UNNAMED_MAJOR { if driver.major == Major::UNNAMED_MAJOR {
let dev_num = CharDevOps::alloc_chardev_region( let dev_num = CharDevOps::alloc_chardev_region(
@ -69,11 +77,12 @@ impl TtyDriverManager {
driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED; driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
// 加入全局TtyDriver表 // 加入全局TtyDriver表
TTY_DRIVERS.lock().push(Arc::new(driver)); let driver = Arc::new(driver);
TTY_DRIVERS.lock().push(driver.clone());
// TODO: 加入procfs? // TODO: 加入procfs?
Ok(()) Ok(driver)
} }
} }
@ -104,11 +113,13 @@ pub struct TtyDriver {
/// 驱动程序标志 /// 驱动程序标志
flags: TtyDriverFlag, flags: TtyDriverFlag,
/// pty链接此driver的入口 /// pty链接此driver的入口
pty: Option<Arc<TtyDriver>>, other_pty_driver: RwLock<Weak<TtyDriver>>,
/// 具体类型的tty驱动方法 /// 具体类型的tty驱动方法
driver_funcs: Arc<dyn TtyOperation>, driver_funcs: Arc<dyn TtyOperation>,
/// 管理的tty设备列表 /// 管理的tty设备列表
ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>, ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
/// 管理的端口列表
ports: RwLock<Vec<Arc<dyn TtyPort>>>,
// procfs入口? // procfs入口?
} }
@ -124,6 +135,10 @@ impl TtyDriver {
default_termios: Termios, default_termios: Termios,
driver_funcs: Arc<dyn TtyOperation>, driver_funcs: Arc<dyn TtyOperation>,
) -> Self { ) -> Self {
let mut ports: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(count as usize);
for _ in 0..count {
ports.push(Arc::new(DefaultTtyPort::new()))
}
TtyDriver { TtyDriver {
driver_name: Default::default(), driver_name: Default::default(),
name: node_name, name: node_name,
@ -135,10 +150,11 @@ impl TtyDriver {
tty_driver_sub_type: Default::default(), tty_driver_sub_type: Default::default(),
init_termios: default_termios, init_termios: default_termios,
flags: TtyDriverFlag::empty(), flags: TtyDriverFlag::empty(),
pty: Default::default(), other_pty_driver: Default::default(),
driver_funcs, driver_funcs,
ttys: SpinLock::new(HashMap::new()), ttys: SpinLock::new(HashMap::new()),
saved_termios: Vec::with_capacity(count as usize), saved_termios: Vec::with_capacity(count as usize),
ports: RwLock::new(ports),
} }
} }
@ -162,34 +178,65 @@ impl TtyDriver {
self.driver_funcs.clone() self.driver_funcs.clone()
} }
#[inline]
pub fn init_termios(&self) -> Termios {
self.init_termios
}
#[inline]
pub fn init_termios_mut(&mut self) -> &mut Termios {
&mut self.init_termios
}
#[inline]
pub fn other_pty_driver(&self) -> Option<Arc<TtyDriver>> {
self.other_pty_driver.read().upgrade()
}
pub fn set_other_pty_driver(&self, driver: Weak<TtyDriver>) {
*self.other_pty_driver.write() = driver
}
#[inline]
pub fn set_subtype(&mut self, tp: TtyDriverSubType) {
self.tty_driver_sub_type = tp;
}
#[inline]
pub fn ttys(&self) -> SpinLockGuard<HashMap<usize, Arc<TtyCore>>> {
self.ttys.lock()
}
#[inline]
pub fn saved_termios(&self) -> &Vec<Termios> {
&self.saved_termios
}
#[inline] #[inline]
pub fn flags(&self) -> TtyDriverFlag { pub fn flags(&self) -> TtyDriverFlag {
self.flags self.flags
} }
#[inline] #[inline]
fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> { fn lookup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
let device_guard = self.ttys.lock(); let ret = self
return device_guard.get(&index).cloned(); .driver_funcs()
.lookup(index, TtyDriverPrivateData::Unused);
if let Err(SystemError::ENOSYS) = ret {
let device_guard = self.ttys.lock();
return device_guard.get(&index).cloned();
}
ret.ok()
} }
fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> { fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
let tty = tty_core.core(); let tty = tty_core.core();
let tty_index = tty.index(); tty.init_termios();
// 初始化termios
if !self.flags.contains(TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) {
// 先查看是否有已经保存的termios
if let Some(t) = self.saved_termios.get(tty_index) {
let mut termios = *t;
termios.line = self.init_termios.line;
tty.set_termios(termios);
}
}
// TODO:设置termios波特率 // TODO:设置termios波特率
tty.add_count(); tty.add_count();
self.ttys.lock().insert(tty_index, tty_core); self.ttys.lock().insert(tty.index(), tty_core);
Ok(()) Ok(())
} }
@ -210,7 +257,10 @@ impl TtyDriver {
Ok(()) Ok(())
} }
fn init_tty_device(driver: Arc<TtyDriver>, index: usize) -> Result<Arc<TtyCore>, SystemError> { pub fn init_tty_device(
driver: Arc<TtyDriver>,
index: usize,
) -> Result<Arc<TtyCore>, SystemError> {
let tty = TtyCore::new(driver.clone(), index); let tty = TtyCore::new(driver.clone(), index);
Self::driver_install_tty(driver.clone(), tty.clone())?; Self::driver_install_tty(driver.clone(), tty.clone())?;
@ -218,8 +268,9 @@ impl TtyDriver {
let core = tty.core(); let core = tty.core();
if core.port().is_none() { if core.port().is_none() {
TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty)); let ports = driver.ports.read();
tty.set_port(TTY_PORTS[core.index()].clone()); ports[core.index()].setup_internal_tty(Arc::downgrade(&tty));
tty.set_port(ports[core.index()].clone());
} }
TtyLdiscManager::ldisc_setup(tty.clone(), None)?; TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
@ -228,11 +279,8 @@ impl TtyDriver {
} }
/// ## 通过设备号找到对应驱动并且初始化Tty /// ## 通过设备号找到对应驱动并且初始化Tty
pub fn open_tty(dev_num: DeviceNumber) -> Result<Arc<TtyCore>, SystemError> { pub fn open_tty(index: usize, driver: Arc<TtyDriver>) -> Result<Arc<TtyCore>, SystemError> {
let (index, driver) = let tty = match driver.lookup_tty(index) {
TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
let tty = match driver.lockup_tty(index) {
Some(tty) => { Some(tty) => {
// TODO: 暂时这么写因为还没写TtyPort // TODO: 暂时这么写因为还没写TtyPort
if tty.core().port().is_none() { if tty.core().port().is_none() {
@ -247,8 +295,6 @@ impl TtyDriver {
None => Self::init_tty_device(driver, index)?, None => Self::init_tty_device(driver, index)?,
}; };
CURRENT_VCNUM.store(index as isize, Ordering::SeqCst);
return Ok(tty); return Ok(tty);
} }
@ -259,10 +305,6 @@ impl TtyDriver {
pub fn tty_driver_sub_type(&self) -> TtyDriverSubType { pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
self.tty_driver_sub_type self.tty_driver_sub_type
} }
pub fn init_termios(&self) -> Termios {
self.init_termios
}
} }
impl KObject for TtyDriver { impl KObject for TtyDriver {
@ -368,7 +410,9 @@ pub trait TtyOperation: Sync + Send + Debug {
fn flush_chars(&self, tty: &TtyCoreData); fn flush_chars(&self, tty: &TtyCoreData);
fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError>; fn put_char(&self, _tty: &TtyCoreData, _ch: u8) -> Result<(), SystemError> {
Err(SystemError::ENOSYS)
}
fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> { fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
Err(SystemError::ENOSYS) Err(SystemError::ENOSYS)
@ -391,6 +435,16 @@ pub trait TtyOperation: Sync + Send + Debug {
fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> { fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
Err(SystemError::ENOSYS) Err(SystemError::ENOSYS)
} }
fn lookup(
&self,
_index: usize,
_priv_data: TtyDriverPrivateData,
) -> Result<Arc<TtyCore>, SystemError> {
Err(SystemError::ENOSYS)
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
} }
#[allow(dead_code)] #[allow(dead_code)]

View File

@ -7,7 +7,7 @@ use crate::filesystem::vfs::file::FileMode;
use super::{ use super::{
termios::Termios, termios::Termios,
tty_core::{TtyCore, TtyCoreData}, tty_core::{TtyCore, TtyCoreData, TtyFlag},
}; };
pub mod ntty; pub mod ntty;
@ -99,7 +99,7 @@ impl TtyLdiscManager {
/// ### 参数 /// ### 参数
/// - tty需要设置的tty /// - tty需要设置的tty
/// - o_tty: other tty 用于pty pair /// - o_tty: other tty 用于pty pair
pub fn ldisc_setup(tty: Arc<TtyCore>, _o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> { pub fn ldisc_setup(tty: Arc<TtyCore>, o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
let ld = tty.ldisc(); let ld = tty.ldisc();
let ret = ld.open(tty); let ret = ld.open(tty);
@ -109,7 +109,16 @@ impl TtyLdiscManager {
} }
} }
// TODO: 处理PTY // 处理PTY
if let Some(o_tty) = o_tty {
let ld = o_tty.ldisc();
let ret: Result<(), SystemError> = ld.open(o_tty.clone());
if ret.is_err() {
o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN);
let _ = ld.close(o_tty.clone());
}
}
Ok(()) Ok(())
} }

View File

@ -10,7 +10,7 @@ use crate::{
arch::ipc::signal::Signal, arch::ipc::signal::Signal,
driver::tty::{ driver::tty::{
termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios}, termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios},
tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd}, tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
tty_driver::{TtyDriverFlag, TtyOperation}, tty_driver::{TtyDriverFlag, TtyOperation},
tty_job_control::TtyJobCtrlManager, tty_job_control::TtyJobCtrlManager,
}, },
@ -812,6 +812,10 @@ impl NTtyData {
self.read_flags.set_all(false); self.read_flags.set_all(false);
self.pushing = false; self.pushing = false;
self.lookahead_count = 0; self.lookahead_count = 0;
if tty.core().link().is_some() {
self.packet_mode_flush(tty.core());
}
} }
} }
@ -1521,6 +1525,17 @@ impl NTtyData {
} }
Ok(1) Ok(1)
} }
fn packet_mode_flush(&self, tty: &TtyCoreData) {
let link = tty.link().unwrap();
if link.core().contorl_info_irqsave().packet {
tty.contorl_info_irqsave()
.pktstatus
.insert(TtyPacketStatus::TIOCPKT_FLUSHREAD);
link.core().read_wq().wakeup_all();
}
}
} }
impl TtyLineDiscipline for NTtyLinediscipline { impl TtyLineDiscipline for NTtyLinediscipline {
@ -1551,7 +1566,10 @@ impl TtyLineDiscipline for NTtyLinediscipline {
ldata.lookahead_count = 0; ldata.lookahead_count = 0;
// todo: kick worker? // todo: kick worker?
// todo: packet mode? // packet mode?
if core.link().is_some() {
ldata.packet_mode_flush(core);
}
Ok(()) Ok(())
} }
@ -1618,12 +1636,31 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} }
} }
let packet = core.contorl_info_irqsave().packet;
let mut ret: Result<usize, SystemError> = Ok(0); let mut ret: Result<usize, SystemError> = Ok(0);
// 记录读取前 的tail // 记录读取前 的tail
let tail = ldata.read_tail; let tail = ldata.read_tail;
drop(ldata); drop(ldata);
while nr != 0 { while nr != 0 {
// todo: 处理packet模式 // todo: 处理packet模式
if packet {
let link = core.link().unwrap();
let link = link.core();
let mut ctrl = link.contorl_info_irqsave();
if !ctrl.pktstatus.is_empty() {
if offset != 0 {
break;
}
let cs = ctrl.pktstatus;
ctrl.pktstatus = TtyPacketStatus::empty();
buf[offset] = cs.bits();
offset += 1;
// nr -= 1;
break;
}
}
let mut ldata = self.disc_data(); let mut ldata = self.disc_data();
let core = tty.core(); let core = tty.core();
@ -1676,7 +1713,11 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} else { } else {
// 非标准模式 // 非标准模式
// todo: 处理packet模式 // todo: 处理packet模式
if packet && offset == 0 {
buf[offset] = TtyPacketStatus::TIOCPKT_DATA.bits();
offset += 1;
nr -= 1;
}
// 拷贝数据 // 拷贝数据
if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)? if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
&& offset >= minimum && offset >= minimum
@ -2025,7 +2066,14 @@ impl TtyLineDiscipline for NTtyLinediscipline {
if core.contorl_info_irqsave().packet { if core.contorl_info_irqsave().packet {
let link = core.link(); let link = core.link();
if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 { if link.is_some()
&& !link
.unwrap()
.core()
.contorl_info_irqsave()
.pktstatus
.is_empty()
{
event.insert( event.insert(
EPollEventType::EPOLLPRI EPollEventType::EPOLLPRI
| EPollEventType::EPOLLIN | EPollEventType::EPOLLIN

View File

@ -1,36 +1,29 @@
use core::{fmt::Debug, sync::atomic::Ordering}; use core::{fmt::Debug, sync::atomic::Ordering};
use alloc::{ use alloc::sync::{Arc, Weak};
sync::{Arc, Weak},
vec::Vec,
};
use kdepends::thingbuf::mpsc; use kdepends::thingbuf::mpsc;
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::libs::spinlock::{SpinLock, SpinLockGuard};
driver::tty::virtual_terminal::MAX_NR_CONSOLES,
libs::spinlock::{SpinLock, SpinLockGuard}, use super::{
tty_core::TtyCore,
virtual_terminal::{virtual_console::CURRENT_VCNUM, VIRT_CONSOLES},
}; };
use super::{tty_core::TtyCore, virtual_terminal::virtual_console::CURRENT_VCNUM};
const TTY_PORT_BUFSIZE: usize = 4096; const TTY_PORT_BUFSIZE: usize = 4096;
lazy_static! {
pub static ref TTY_PORTS: Vec<Arc<dyn TtyPort>> = {
let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
for _ in 0..MAX_NR_CONSOLES as usize {
v.push(Arc::new(DefaultTtyPort::new()))
}
v
};
}
/// 获取当前tty port /// 获取当前tty port
#[inline] #[inline]
pub fn current_tty_port() -> Arc<dyn TtyPort> { pub fn current_tty_port() -> Arc<dyn TtyPort> {
TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone() VIRT_CONSOLES[CURRENT_VCNUM.load(Ordering::SeqCst) as usize]
.lock_irqsave()
.port()
}
#[inline]
pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
VIRT_CONSOLES[index].lock_irqsave().port()
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -41,6 +34,14 @@ pub struct TtyPortData {
sender: mpsc::Sender<u8>, sender: mpsc::Sender<u8>,
receiver: mpsc::Receiver<u8>, receiver: mpsc::Receiver<u8>,
tty: Weak<TtyCore>, tty: Weak<TtyCore>,
/// 内部tty即与port直接相连的
internal_tty: Weak<TtyCore>,
}
impl Default for TtyPortData {
fn default() -> Self {
Self::new()
}
} }
impl TtyPortData { impl TtyPortData {
@ -52,11 +53,12 @@ impl TtyPortData {
sender, sender,
receiver, receiver,
tty: Weak::new(), tty: Weak::new(),
internal_tty: Weak::new(),
} }
} }
pub fn tty(&self) -> Option<Arc<TtyCore>> { pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
self.tty.upgrade() self.internal_tty.upgrade()
} }
} }
@ -80,13 +82,13 @@ pub trait TtyPort: Sync + Send + Debug {
} }
/// 为port设置tty /// 为port设置tty
fn setup_tty(&self, tty: Weak<TtyCore>) { fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
self.port_data().tty = tty; self.port_data().internal_tty = tty;
} }
/// 作为客户端的tty ports接收数据 /// 作为客户端的tty ports接收数据
fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> { fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
let tty = self.port_data().tty.upgrade().unwrap(); let tty = self.port_data().internal_tty().unwrap();
let ld = tty.ldisc(); let ld = tty.ldisc();

View File

@ -1,6 +1,10 @@
use core::sync::atomic::Ordering; use core::sync::atomic::Ordering;
use alloc::{string::String, sync::Arc, vec::Vec}; use alloc::{
string::{String, ToString},
sync::Arc,
vec::Vec,
};
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
@ -21,7 +25,7 @@ use super::{
console::ConsoleSwitch, console::ConsoleSwitch,
termios::{InputMode, TTY_STD_TERMIOS}, termios::{InputMode, TTY_STD_TERMIOS},
tty_core::{TtyCore, TtyCoreData}, tty_core::{TtyCore, TtyCoreData},
tty_device::TtyDevice, tty_device::{TtyDevice, TtyType},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverType, TtyOperation}, tty_driver::{TtyDriver, TtyDriverManager, TtyDriverType, TtyOperation},
}; };
@ -191,8 +195,12 @@ impl TtyOperation for TtyConsoleDriverInner {
tty_core.termios_write().input_mode.remove(InputMode::IUTF8); tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
} }
// 设置tty的端口为vc端口
vc_data.port().setup_internal_tty(Arc::downgrade(&tty));
tty.set_port(vc_data.port());
// 加入sysfs // 加入sysfs
CURRENT_VCNUM.store(tty_core.index() as isize, Ordering::SeqCst);
Ok(()) Ok(())
} }
@ -207,6 +215,9 @@ impl TtyOperation for TtyConsoleDriverInner {
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894 /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
#[inline(never)] #[inline(never)]
fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> { fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
// if String::from_utf8_lossy(buf) == "Hello world!\n" {
// loop {}
// }
let ret = self.do_write(tty, buf, nr); let ret = self.do_write(tty, buf, nr);
self.flush_chars(tty); self.flush_chars(tty);
ret ret
@ -227,6 +238,10 @@ impl TtyOperation for TtyConsoleDriverInner {
// TODO // TODO
Err(SystemError::ENOIOCTLCMD) Err(SystemError::ENOIOCTLCMD)
} }
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
Ok(())
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -264,11 +279,12 @@ pub struct DrawRegion {
pub fn vty_init() -> Result<(), SystemError> { pub fn vty_init() -> Result<(), SystemError> {
// 注册虚拟终端设备并将虚拟终端设备加入到文件系统 // 注册虚拟终端设备并将虚拟终端设备加入到文件系统
let vc0 = TtyDevice::new( let vc0 = TtyDevice::new(
"vc0", "vc0".to_string(),
IdTable::new( IdTable::new(
String::from("vc0"), String::from("vc0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)), Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
), ),
TtyType::Tty,
); );
// 注册tty设备 // 注册tty设备
// CharDevOps::cdev_add( // CharDevOps::cdev_add(

View File

@ -9,7 +9,11 @@ use bitmap::{traits::BitMapOps, StaticBitmap};
use crate::{ use crate::{
driver::{ driver::{
serial::serial8250::send_to_default_serial8250_port, serial::serial8250::send_to_default_serial8250_port,
tty::{console::ConsoleSwitch, ConsoleFont, KDMode}, tty::{
console::ConsoleSwitch,
tty_port::{DefaultTtyPort, TtyPort},
ConsoleFont, KDMode,
},
}, },
libs::{font::FontDesc, rwlock::RwLock}, libs::{font::FontDesc, rwlock::RwLock},
process::Pid, process::Pid,
@ -142,6 +146,9 @@ pub struct VirtualConsoleData {
/// 对应的Console Driver funcs /// 对应的Console Driver funcs
driver_funcs: Option<Weak<dyn ConsoleSwitch>>, driver_funcs: Option<Weak<dyn ConsoleSwitch>>,
/// 对应端口
port: Arc<dyn TtyPort>,
} }
impl VirtualConsoleData { impl VirtualConsoleData {
@ -204,9 +211,15 @@ impl VirtualConsoleData {
driver_funcs: None, driver_funcs: None,
cursor_type: VcCursor::empty(), cursor_type: VcCursor::empty(),
num, num,
port: Arc::new(DefaultTtyPort::new()),
} }
} }
#[inline]
pub fn port(&self) -> Arc<dyn TtyPort> {
self.port.clone()
}
pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) { pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
if let Some(rows) = rows { if let Some(rows) = rows {
self.rows = rows; self.rows = rows;

View File

@ -383,11 +383,15 @@ impl DeviceINode for FbDevice {
} }
impl IndexNode for FbDevice { impl IndexNode for FbDevice {
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(()) Ok(())
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
Ok(()) Ok(())
} }
fn read_at( fn read_at(
@ -395,7 +399,7 @@ impl IndexNode for FbDevice {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let fb = self.inner.lock().fb.upgrade().unwrap(); let fb = self.inner.lock().fb.upgrade().unwrap();
return fb.fb_read(&mut buf[0..len], offset); return fb.fb_read(&mut buf[0..len], offset);
@ -406,7 +410,7 @@ impl IndexNode for FbDevice {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let fb = self.inner.lock().fb.upgrade().unwrap(); let fb = self.inner.lock().fb.upgrade().unwrap();
return fb.fb_write(&buf[0..len], offset); return fb.fb_write(&buf[0..len], offset);

View File

@ -147,6 +147,10 @@ impl DevFS {
if name.starts_with("tty") && name.len() > 3 { if name.starts_with("tty") && name.len() > 3 {
dev_root_inode.add_dev(name, device.clone())?; dev_root_inode.add_dev(name, device.clone())?;
} }
// ptmx设备
if name == "ptmx" {
dev_root_inode.add_dev(name, device.clone())?;
}
device.set_fs(dev_char_inode.0.lock().fs.clone()); device.set_fs(dev_char_inode.0.lock().fs.clone());
} }
FileType::BlockDevice => { FileType::BlockDevice => {
@ -388,13 +392,13 @@ impl IndexNode for LockedDevFSInode {
fn open( fn open(
&self, &self,
_data: &mut super::vfs::FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode, _mode: &FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -523,7 +527,7 @@ impl IndexNode for LockedDevFSInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut super::vfs::file::FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
kerror!("DevFS: read_at is not supported!"); kerror!("DevFS: read_at is not supported!");
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
@ -535,7 +539,7 @@ impl IndexNode for LockedDevFSInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut super::vfs::file::FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }

View File

@ -4,6 +4,7 @@ use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{ use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::{libs::spinlock::SpinLock, time::TimeSpec}; use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{ use alloc::{
string::String, string::String,
@ -71,11 +72,15 @@ impl IndexNode for LockedNullInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -109,7 +114,7 @@ impl IndexNode for LockedNullInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return Ok(0); return Ok(0);
} }
@ -120,7 +125,7 @@ impl IndexNode for LockedNullInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);

View File

@ -4,6 +4,7 @@ use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{ use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::{libs::spinlock::SpinLock, time::TimeSpec}; use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{ use alloc::{
string::String, string::String,
@ -71,11 +72,15 @@ impl IndexNode for LockedZeroInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -109,7 +114,7 @@ impl IndexNode for LockedZeroInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
@ -128,7 +133,7 @@ impl IndexNode for LockedZeroInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);

View File

@ -0,0 +1,290 @@
use core::sync::atomic::{AtomicU32, Ordering};
use alloc::{
collections::BTreeMap,
string::{String, ToString},
sync::{Arc, Weak},
vec::Vec,
};
use ida::IdAllocator;
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::{
driver::{
base::device::{
device_number::{DeviceNumber, Major},
IdTable,
},
tty::{
pty::unix98pty::NR_UNIX98_PTY_MAX,
tty_device::{PtyType, TtyDevice, TtyType},
},
},
filesystem::vfs::{syscall::ModeType, FileType, ROOT_INODE},
init::initcall::INITCALL_FS,
libs::spinlock::{SpinLock, SpinLockGuard},
time::TimeSpec,
};
use super::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata,
};
const DEV_PTYFS_MAX_NAMELEN: usize = 16;
#[allow(dead_code)]
const PTY_NR_LIMIT: usize = 4096;
#[derive(Debug)]
pub struct DevPtsFs {
/// 根节点
root_inode: Arc<LockedDevPtsFSInode>,
pts_ida: IdAllocator,
pts_count: AtomicU32,
}
impl DevPtsFs {
pub fn new() -> Arc<Self> {
let root_inode = Arc::new(LockedDevPtsFSInode::new());
let ret = Arc::new(Self {
root_inode,
pts_ida: IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize),
pts_count: AtomicU32::new(0),
});
ret.root_inode.set_fs(Arc::downgrade(&ret));
ret
}
pub fn alloc_index(&self) -> Result<usize, SystemError> {
self.pts_ida.alloc().ok_or(SystemError::ENOSPC)
}
}
impl FileSystem for DevPtsFs {
fn root_inode(&self) -> Arc<dyn IndexNode> {
self.root_inode.clone()
}
fn info(&self) -> super::vfs::FsInfo {
return FsInfo {
blk_dev_id: 0,
max_name_len: DEV_PTYFS_MAX_NAMELEN,
};
}
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn name(&self) -> &str {
"devpts"
}
fn super_block(&self) -> super::vfs::SuperBlock {
todo!()
}
}
#[derive(Debug)]
pub struct LockedDevPtsFSInode {
inner: SpinLock<PtsDevInode>,
}
impl LockedDevPtsFSInode {
pub fn new() -> Self {
Self {
inner: SpinLock::new(PtsDevInode {
fs: Weak::new(),
children: Some(BTreeMap::new()),
metadata: Metadata {
dev_id: 0,
inode_id: generate_inode_id(),
size: 0,
blk_size: 0,
blocks: 0,
atime: TimeSpec::default(),
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::Dir,
mode: ModeType::from_bits_truncate(0x777),
nlinks: 1,
uid: 0,
gid: 0,
raw_dev: DeviceNumber::default(),
},
}),
}
}
pub fn set_fs(&self, fs: Weak<DevPtsFs>) {
self.inner.lock().fs = fs;
}
}
#[derive(Debug)]
pub struct PtsDevInode {
fs: Weak<DevPtsFs>,
children: Option<BTreeMap<String, Arc<TtyDevice>>>,
metadata: Metadata,
}
impl PtsDevInode {
pub fn children_unchecked(&self) -> &BTreeMap<String, Arc<TtyDevice>> {
self.children.as_ref().unwrap()
}
pub fn children_unchecked_mut(&mut self) -> &mut BTreeMap<String, Arc<TtyDevice>> {
self.children.as_mut().unwrap()
}
}
impl IndexNode for LockedDevPtsFSInode {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &super::vfs::file::FileMode,
) -> Result<(), SystemError> {
Ok(())
}
fn metadata(&self) -> Result<super::vfs::Metadata, SystemError> {
let inode = self.inner.lock();
let metadata = inode.metadata.clone();
return Ok(metadata);
}
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// TODO: 回收
Ok(())
}
fn read_at(
&self,
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
todo!()
}
fn write_at(
&self,
_offset: usize,
_len: usize,
_buf: &[u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
todo!()
}
fn fs(&self) -> alloc::sync::Arc<dyn super::vfs::FileSystem> {
self.inner.lock().fs.upgrade().unwrap()
}
fn as_any_ref(&self) -> &dyn core::any::Any {
todo!()
}
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
let info = self.metadata()?;
if info.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
let mut keys: Vec<String> = Vec::new();
keys.push(String::from("."));
keys.push(String::from(".."));
keys.append(
&mut self
.inner
.lock()
.children_unchecked()
.keys()
.cloned()
.collect(),
);
return Ok(keys);
}
fn create_with_data(
&self,
name: &str,
file_type: FileType,
_mode: super::vfs::syscall::ModeType,
_data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
if file_type != FileType::CharDevice {
return Err(SystemError::ENOSYS);
}
let mut guard = self.inner.lock();
if guard.children_unchecked_mut().contains_key(name) {
return Err(SystemError::EEXIST);
}
let fs = guard.fs.upgrade().unwrap();
let result = TtyDevice::new(
name.to_string(),
IdTable::new(name.to_string(), None),
TtyType::Pty(PtyType::Pts),
);
let mut metadata = result.metadata()?;
metadata.mode.insert(ModeType::S_IFCHR);
metadata.raw_dev =
DeviceNumber::new(Major::UNIX98_PTY_SLAVE_MAJOR, name.parse::<u32>().unwrap());
result.set_metadata(&metadata)?;
guard
.children_unchecked_mut()
.insert(name.to_string(), result.clone());
fs.pts_count.fetch_add(1, Ordering::SeqCst);
Ok(result)
}
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
let guard = self.inner.lock();
if let Some(dev) = guard.children_unchecked().get(name) {
Ok(dev.clone() as Arc<dyn IndexNode>)
} else {
Err(SystemError::ENOENT)
}
}
fn unlink(&self, name: &str) -> Result<(), SystemError> {
let mut guard = self.inner.lock();
guard.children_unchecked_mut().remove(name);
Ok(())
}
}
#[unified_init(INITCALL_FS)]
#[inline(never)]
pub fn devpts_init() -> Result<(), SystemError> {
let dev_inode = ROOT_INODE().find("dev")?;
let pts_inode = dev_inode.create("pts", FileType::Dir, ModeType::from_bits_truncate(0o755))?;
// 创建 devptsfs 实例
let ptsfs: Arc<DevPtsFs> = DevPtsFs::new();
// let mountfs = dev_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
pts_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
kinfo!("DevPtsFs mounted.");
Ok(())
}

View File

@ -1369,7 +1369,7 @@ impl IndexNode for LockedFATInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock(); let mut guard: SpinLockGuard<FATInode> = self.0.lock();
match &guard.inode_type { match &guard.inode_type {
@ -1397,7 +1397,7 @@ impl IndexNode for LockedFATInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock(); let mut guard: SpinLockGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap(); let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
@ -1566,11 +1566,15 @@ impl IndexNode for LockedFATInode {
return Ok(target); return Ok(target);
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }

View File

@ -154,7 +154,11 @@ impl IndexNode for KernFSInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
if let Some(callback) = self.callback { if let Some(callback) = self.callback {
let callback_data = let callback_data =
KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
@ -164,7 +168,7 @@ impl IndexNode for KernFSInode {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -315,7 +319,7 @@ impl IndexNode for KernFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if self.inode_type == KernInodeType::SymLink { if self.inode_type == KernInodeType::SymLink {
let inner = self.inner.read(); let inner = self.inner.read();
@ -359,7 +363,7 @@ impl IndexNode for KernFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if self.inode_type != KernInodeType::File { if self.inode_type != KernInodeType::File {
return Err(SystemError::EISDIR); return Err(SystemError::EISDIR);

View File

@ -1,4 +1,5 @@
pub mod devfs; pub mod devfs;
pub mod devpts;
pub mod fat; pub mod fat;
pub mod kernfs; pub mod kernfs;
pub mod mbr; pub mod mbr;

View File

@ -433,7 +433,11 @@ impl ProcFS {
} }
impl IndexNode for LockedProcFSInode { impl IndexNode for LockedProcFSInode {
fn open(&self, data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
mut data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
// 加锁 // 加锁
let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock(); let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
@ -457,7 +461,7 @@ impl IndexNode for LockedProcFSInode {
return Ok(()); return Ok(());
} }
fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, mut data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let guard: SpinLockGuard<ProcFSInode> = self.0.lock(); let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
// 如果inode类型为文件夹则直接返回成功 // 如果inode类型为文件夹则直接返回成功
if let FileType::Dir = guard.metadata.file_type { if let FileType::Dir = guard.metadata.file_type {
@ -474,7 +478,7 @@ impl IndexNode for LockedProcFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
@ -488,8 +492,8 @@ impl IndexNode for LockedProcFSInode {
} }
// 获取数据信息 // 获取数据信息
let private_data = match data { let mut private_data = match &*data {
FilePrivateData::Procfs(p) => p, FilePrivateData::Procfs(p) => p.clone(),
_ => { _ => {
panic!("ProcFS: FilePrivateData mismatch!"); panic!("ProcFS: FilePrivateData mismatch!");
} }
@ -497,8 +501,12 @@ impl IndexNode for LockedProcFSInode {
// 根据文件类型读取相应数据 // 根据文件类型读取相应数据
match inode.fdata.ftype { match inode.fdata.ftype {
ProcFileType::ProcStatus => return inode.proc_read(offset, len, buf, private_data), ProcFileType::ProcStatus => {
ProcFileType::ProcMeminfo => return inode.proc_read(offset, len, buf, private_data), return inode.proc_read(offset, len, buf, &mut private_data)
}
ProcFileType::ProcMeminfo => {
return inode.proc_read(offset, len, buf, &mut private_data)
}
ProcFileType::ProcKmsg => (), ProcFileType::ProcKmsg => (),
ProcFileType::Default => (), ProcFileType::Default => (),
}; };
@ -523,7 +531,7 @@ impl IndexNode for LockedProcFSInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
} }

View File

@ -167,13 +167,13 @@ impl IndexNode for LockedRamFSInode {
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
fn open( fn open(
&self, &self,
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
_mode: &super::vfs::file::FileMode, _mode: &super::vfs::file::FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
return Ok(()); return Ok(());
@ -184,7 +184,7 @@ impl IndexNode for LockedRamFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
@ -216,7 +216,7 @@ impl IndexNode for LockedRamFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
if buf.len() < len { if buf.len() < len {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);

View File

@ -19,6 +19,7 @@ use crate::{
use super::{ use super::{
file::FileMode, file::FileMode,
mount::MountFSInode,
utils::{rsplit_path, user_path_at}, utils::{rsplit_path, user_path_at},
IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES, IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
}; };
@ -103,9 +104,9 @@ fn do_migrate(
.unwrap_or_else(|_| panic!("Failed to create '/{mountpoint_name}' in migrating")) .unwrap_or_else(|_| panic!("Failed to create '/{mountpoint_name}' in migrating"))
}; };
// 迁移挂载点 // 迁移挂载点
mountpoint let inode = mountpoint.arc_any().downcast::<MountFSInode>().unwrap();
.mount(fs.inner_filesystem()) inode.do_mount(inode.inode_id(), fs.self_ref())?;
.unwrap_or_else(|_| panic!("Failed to migrate {mountpoint_name} "));
return Ok(()); return Ok(());
} }

View File

@ -1,3 +1,5 @@
use core::sync::atomic::{AtomicUsize, Ordering};
use alloc::{ use alloc::{
string::String, string::String,
sync::{Arc, Weak}, sync::{Arc, Weak},
@ -13,7 +15,7 @@ use crate::{
filesystem::procfs::ProcfsFilePrivateData, filesystem::procfs::ProcfsFilePrivateData,
ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, ipc::pipe::{LockedPipeInode, PipeFsPrivateData},
kerror, kerror,
libs::spinlock::SpinLock, libs::{rwlock::RwLock, spinlock::SpinLock},
net::{ net::{
event_poll::{EPollItem, EPollPrivateData, EventPoll}, event_poll::{EPollItem, EPollPrivateData, EventPoll},
socket::SocketInode, socket::SocketInode,
@ -121,14 +123,14 @@ impl FileMode {
pub struct File { pub struct File {
inode: Arc<dyn IndexNode>, inode: Arc<dyn IndexNode>,
/// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量 /// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量
offset: usize, offset: AtomicUsize,
/// 文件的打开模式 /// 文件的打开模式
mode: FileMode, mode: RwLock<FileMode>,
/// 文件类型 /// 文件类型
file_type: FileType, file_type: FileType,
/// readdir时候用的暂存的本次循环中所有子目录项的名字的数组 /// readdir时候用的暂存的本次循环中所有子目录项的名字的数组
readdir_subdirs_name: Vec<String>, readdir_subdirs_name: SpinLock<Vec<String>>,
pub private_data: FilePrivateData, pub private_data: SpinLock<FilePrivateData>,
} }
impl File { impl File {
@ -145,16 +147,16 @@ impl File {
} }
} }
let mut f = File { let f = File {
inode, inode,
offset: 0, offset: AtomicUsize::new(0),
mode, mode: RwLock::new(mode),
file_type, file_type,
readdir_subdirs_name: Vec::new(), readdir_subdirs_name: SpinLock::new(Vec::default()),
private_data: FilePrivateData::default(), private_data: SpinLock::new(FilePrivateData::default()),
}; };
// kdebug!("inode:{:?}",f.inode); // kdebug!("inode:{:?}",f.inode);
f.inode.open(&mut f.private_data, &mode)?; f.inode.open(f.private_data.lock(), &mode)?;
return Ok(f); return Ok(f);
} }
@ -166,8 +168,13 @@ impl File {
/// ///
/// @return Ok(usize) 成功读取的字节数 /// @return Ok(usize) 成功读取的字节数
/// @return Err(SystemError) 错误码 /// @return Err(SystemError) 错误码
pub fn read(&mut self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> { pub fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
self.do_read(self.offset, len, buf, true) self.do_read(
self.offset.load(core::sync::atomic::Ordering::SeqCst),
len,
buf,
true,
)
} }
/// @brief 从buffer向文件写入指定的字节数的数据 /// @brief 从buffer向文件写入指定的字节数的数据
@ -177,8 +184,13 @@ impl File {
/// ///
/// @return Ok(usize) 成功写入的字节数 /// @return Ok(usize) 成功写入的字节数
/// @return Err(SystemError) 错误码 /// @return Err(SystemError) 错误码
pub fn write(&mut self, len: usize, buf: &[u8]) -> Result<usize, SystemError> { pub fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
self.do_write(self.offset, len, buf, true) self.do_write(
self.offset.load(core::sync::atomic::Ordering::SeqCst),
len,
buf,
true,
)
} }
/// ## 从文件中指定的偏移处读取指定的字节数到buf中 /// ## 从文件中指定的偏移处读取指定的字节数到buf中
@ -190,12 +202,7 @@ impl File {
/// ///
/// ### 返回值 /// ### 返回值
/// - `Ok(usize)`: 成功读取的字节数 /// - `Ok(usize)`: 成功读取的字节数
pub fn pread( pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
&mut self,
offset: usize,
len: usize,
buf: &mut [u8],
) -> Result<usize, SystemError> {
self.do_read(offset, len, buf, false) self.do_read(offset, len, buf, false)
} }
@ -208,12 +215,12 @@ impl File {
/// ///
/// ### 返回值 /// ### 返回值
/// - `Ok(usize)`: 成功写入的字节数 /// - `Ok(usize)`: 成功写入的字节数
pub fn pwrite(&mut self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> { pub fn pwrite(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
self.do_write(offset, len, buf, false) self.do_write(offset, len, buf, false)
} }
fn do_read( fn do_read(
&mut self, &self,
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
@ -227,17 +234,18 @@ impl File {
let len = self let len = self
.inode .inode
.read_at(offset, len, buf, &mut self.private_data)?; .read_at(offset, len, buf, self.private_data.lock())?;
if update_offset { if update_offset {
self.offset += len; self.offset
.fetch_add(len, core::sync::atomic::Ordering::SeqCst);
} }
Ok(len) Ok(len)
} }
fn do_write( fn do_write(
&mut self, &self,
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
@ -255,10 +263,11 @@ impl File {
} }
let len = self let len = self
.inode .inode
.write_at(offset, len, buf, &mut self.private_data)?; .write_at(offset, len, buf, self.private_data.lock())?;
if update_offset { if update_offset {
self.offset += len; self.offset
.fetch_add(len, core::sync::atomic::Ordering::SeqCst);
} }
Ok(len) Ok(len)
@ -278,7 +287,7 @@ impl File {
/// @brief 调整文件操作指针的位置 /// @brief 调整文件操作指针的位置
/// ///
/// @param origin 调整的起始位置 /// @param origin 调整的起始位置
pub fn lseek(&mut self, origin: SeekFrom) -> Result<usize, SystemError> { pub fn lseek(&self, origin: SeekFrom) -> Result<usize, SystemError> {
let file_type = self.inode.metadata()?.file_type; let file_type = self.inode.metadata()?.file_type;
match file_type { match file_type {
FileType::Pipe | FileType::CharDevice => { FileType::Pipe | FileType::CharDevice => {
@ -289,7 +298,7 @@ impl File {
let pos: i64 = match origin { let pos: i64 = match origin {
SeekFrom::SeekSet(offset) => offset, SeekFrom::SeekSet(offset) => offset,
SeekFrom::SeekCurrent(offset) => self.offset as i64 + offset, SeekFrom::SeekCurrent(offset) => self.offset.load(Ordering::SeqCst) as i64 + offset,
SeekFrom::SeekEnd(offset) => { SeekFrom::SeekEnd(offset) => {
let metadata = self.metadata()?; let metadata = self.metadata()?;
metadata.size + offset metadata.size + offset
@ -303,15 +312,15 @@ impl File {
if pos < 0 { if pos < 0 {
return Err(SystemError::EOVERFLOW); return Err(SystemError::EOVERFLOW);
} }
self.offset = pos as usize; self.offset.store(pos as usize, Ordering::SeqCst);
return Ok(self.offset); return Ok(pos as usize);
} }
/// @brief 判断当前文件是否可读 /// @brief 判断当前文件是否可读
#[inline] #[inline]
pub fn readable(&self) -> Result<(), SystemError> { pub fn readable(&self) -> Result<(), SystemError> {
// 暂时认为只要不是write only, 就可读 // 暂时认为只要不是write only, 就可读
if self.mode == FileMode::O_WRONLY { if *self.mode.read() == FileMode::O_WRONLY {
return Err(SystemError::EPERM); return Err(SystemError::EPERM);
} }
@ -322,7 +331,7 @@ impl File {
#[inline] #[inline]
pub fn writeable(&self) -> Result<(), SystemError> { pub fn writeable(&self) -> Result<(), SystemError> {
// 暂时认为只要不是read only, 就可写 // 暂时认为只要不是read only, 就可写
if self.mode == FileMode::O_RDONLY { if *self.mode.read() == FileMode::O_RDONLY {
return Err(SystemError::EPERM); return Err(SystemError::EPERM);
} }
@ -331,23 +340,24 @@ impl File {
/// @biref 充填dirent结构体 /// @biref 充填dirent结构体
/// @return 返回dirent结构体的大小 /// @return 返回dirent结构体的大小
pub fn readdir(&mut self, dirent: &mut Dirent) -> Result<u64, SystemError> { pub fn readdir(&self, dirent: &mut Dirent) -> Result<u64, SystemError> {
let inode: &Arc<dyn IndexNode> = &self.inode; let inode: &Arc<dyn IndexNode> = &self.inode;
let mut readdir_subdirs_name = self.readdir_subdirs_name.lock();
let offset = self.offset.load(Ordering::SeqCst);
// 如果偏移量为0 // 如果偏移量为0
if self.offset == 0 { if offset == 0 {
// 通过list更新readdir_subdirs_name // 通过list更新readdir_subdirs_name
self.readdir_subdirs_name = inode.list()?; *readdir_subdirs_name = inode.list()?;
self.readdir_subdirs_name.sort(); readdir_subdirs_name.sort();
} }
// kdebug!("sub_entries={sub_entries:?}"); // kdebug!("sub_entries={sub_entries:?}");
// 已经读到末尾 // 已经读到末尾
if self.offset == self.readdir_subdirs_name.len() { if offset == readdir_subdirs_name.len() {
self.offset = 0; self.offset.store(0, Ordering::SeqCst);
return Ok(0); return Ok(0);
} }
let name = &self.readdir_subdirs_name[self.offset]; let name = &readdir_subdirs_name[offset];
let sub_inode: Arc<dyn IndexNode> = match inode.find(name) { let sub_inode: Arc<dyn IndexNode> = match inode.find(name) {
Ok(i) => i, Ok(i) => i,
Err(e) => { Err(e) => {
@ -370,7 +380,7 @@ impl File {
buf[name_bytes.len()] = 0; buf[name_bytes.len()] = 0;
} }
self.offset += 1; self.offset.fetch_add(1, Ordering::SeqCst);
dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64; dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8; dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
@ -392,16 +402,20 @@ impl File {
/// ///
/// @return Option<File> 克隆后的文件结构体。如果克隆失败返回None /// @return Option<File> 克隆后的文件结构体。如果克隆失败返回None
pub fn try_clone(&self) -> Option<File> { pub fn try_clone(&self) -> Option<File> {
let mut res = Self { let res = Self {
inode: self.inode.clone(), inode: self.inode.clone(),
offset: self.offset, offset: AtomicUsize::new(self.offset.load(Ordering::SeqCst)),
mode: self.mode, mode: RwLock::new(self.mode()),
file_type: self.file_type, file_type: self.file_type,
readdir_subdirs_name: self.readdir_subdirs_name.clone(), readdir_subdirs_name: SpinLock::new(self.readdir_subdirs_name.lock().clone()),
private_data: self.private_data.clone(), private_data: SpinLock::new(self.private_data.lock().clone()),
}; };
// 调用inode的open方法让inode知道有新的文件打开了这个inode // 调用inode的open方法让inode知道有新的文件打开了这个inode
if self.inode.open(&mut res.private_data, &res.mode).is_err() { if self
.inode
.open(res.private_data.lock(), &res.mode())
.is_err()
{
return None; return None;
} }
@ -417,32 +431,33 @@ impl File {
/// @brief 获取文件的打开模式 /// @brief 获取文件的打开模式
#[inline] #[inline]
pub fn mode(&self) -> FileMode { pub fn mode(&self) -> FileMode {
return self.mode; return *self.mode.read();
} }
/// 获取文件是否在execve时关闭 /// 获取文件是否在execve时关闭
#[inline] #[inline]
pub fn close_on_exec(&self) -> bool { pub fn close_on_exec(&self) -> bool {
return self.mode.contains(FileMode::O_CLOEXEC); return self.mode().contains(FileMode::O_CLOEXEC);
} }
/// 设置文件是否在execve时关闭 /// 设置文件是否在execve时关闭
#[inline] #[inline]
pub fn set_close_on_exec(&mut self, close_on_exec: bool) { pub fn set_close_on_exec(&self, close_on_exec: bool) {
let mut mode_guard = self.mode.write();
if close_on_exec { if close_on_exec {
self.mode.insert(FileMode::O_CLOEXEC); mode_guard.insert(FileMode::O_CLOEXEC);
} else { } else {
self.mode.remove(FileMode::O_CLOEXEC); mode_guard.remove(FileMode::O_CLOEXEC);
} }
} }
pub fn set_mode(&mut self, mode: FileMode) -> Result<(), SystemError> { pub fn set_mode(&self, mode: FileMode) -> Result<(), SystemError> {
// todo: 是否需要调用inode的open方法以更新private data假如它与mode有关的话? // todo: 是否需要调用inode的open方法以更新private data假如它与mode有关的话?
// 也许需要加个更好的设计让inode知晓文件的打开模式发生了变化让它自己决定是否需要更新private data // 也许需要加个更好的设计让inode知晓文件的打开模式发生了变化让它自己决定是否需要更新private data
// 直接修改文件的打开模式 // 直接修改文件的打开模式
self.mode = mode; *self.mode.write() = mode;
self.private_data.update_mode(mode); self.private_data.lock().update_mode(mode);
return Ok(()); return Ok(());
} }
@ -465,7 +480,7 @@ impl File {
/// ## 向该文件添加一个EPollItem对象 /// ## 向该文件添加一个EPollItem对象
/// ///
/// 在文件状态发生变化时需要向epoll通知 /// 在文件状态发生变化时需要向epoll通知
pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) -> Result<(), SystemError> { pub fn add_epoll(&self, epitem: Arc<EPollItem>) -> Result<(), SystemError> {
match self.file_type { match self.file_type {
FileType::Socket => { FileType::Socket => {
let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); let inode = self.inode.downcast_ref::<SocketInode>().unwrap();
@ -481,7 +496,7 @@ impl File {
let r = self.inode.ioctl( let r = self.inode.ioctl(
EventPoll::ADD_EPOLLITEM, EventPoll::ADD_EPOLLITEM,
&epitem as *const Arc<EPollItem> as usize, &epitem as *const Arc<EPollItem> as usize,
&self.private_data, &self.private_data.lock(),
); );
if r.is_err() { if r.is_err() {
return Err(SystemError::ENOSYS); return Err(SystemError::ENOSYS);
@ -493,7 +508,7 @@ impl File {
} }
/// ## 删除一个绑定的epoll /// ## 删除一个绑定的epoll
pub fn remove_epoll(&mut self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> { pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
match self.file_type { match self.file_type {
FileType::Socket => { FileType::Socket => {
let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); let inode = self.inode.downcast_ref::<SocketInode>().unwrap();
@ -506,13 +521,13 @@ impl File {
} }
pub fn poll(&self) -> Result<usize, SystemError> { pub fn poll(&self) -> Result<usize, SystemError> {
self.inode.poll(&self.private_data) self.inode.poll(&self.private_data.lock())
} }
} }
impl Drop for File { impl Drop for File {
fn drop(&mut self) { fn drop(&mut self) {
let r: Result<(), SystemError> = self.inode.close(&mut self.private_data); let r: Result<(), SystemError> = self.inode.close(self.private_data.lock());
// 打印错误信息 // 打印错误信息
if r.is_err() { if r.is_err() {
kerror!( kerror!(
@ -529,7 +544,7 @@ impl Drop for File {
#[derive(Debug)] #[derive(Debug)]
pub struct FileDescriptorVec { pub struct FileDescriptorVec {
/// 当前进程打开的文件描述符 /// 当前进程打开的文件描述符
fds: Vec<Option<Arc<SpinLock<File>>>>, fds: Vec<Option<Arc<File>>>,
} }
impl FileDescriptorVec { impl FileDescriptorVec {
@ -551,8 +566,8 @@ impl FileDescriptorVec {
let mut res = FileDescriptorVec::new(); let mut res = FileDescriptorVec::new();
for i in 0..FileDescriptorVec::PROCESS_MAX_FD { for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
if let Some(file) = &self.fds[i] { if let Some(file) = &self.fds[i] {
if let Some(file) = file.lock().try_clone() { if let Some(file) = file.try_clone() {
res.fds[i] = Some(Arc::new(SpinLock::new(file))); res.fds[i] = Some(Arc::new(file));
} }
} }
} }
@ -584,7 +599,7 @@ impl FileDescriptorVec {
if let Some(new_fd) = fd { if let Some(new_fd) = fd {
let x = &mut self.fds[new_fd as usize]; let x = &mut self.fds[new_fd as usize];
if x.is_none() { if x.is_none() {
*x = Some(Arc::new(SpinLock::new(file))); *x = Some(Arc::new(file));
return Ok(new_fd); return Ok(new_fd);
} else { } else {
return Err(SystemError::EBADF); return Err(SystemError::EBADF);
@ -593,7 +608,7 @@ impl FileDescriptorVec {
// 没有指定要申请的文件描述符编号 // 没有指定要申请的文件描述符编号
for i in 0..FileDescriptorVec::PROCESS_MAX_FD { for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
if self.fds[i].is_none() { if self.fds[i].is_none() {
self.fds[i] = Some(Arc::new(SpinLock::new(file))); self.fds[i] = Some(Arc::new(file));
return Ok(i as i32); return Ok(i as i32);
} }
} }
@ -606,7 +621,7 @@ impl FileDescriptorVec {
/// ## 参数 /// ## 参数
/// ///
/// - `fd` 文件描述符序号 /// - `fd` 文件描述符序号
pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<SpinLock<File>>> { pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<File>> {
if !FileDescriptorVec::validate_fd(fd) { if !FileDescriptorVec::validate_fd(fd) {
return None; return None;
} }
@ -641,7 +656,7 @@ impl FileDescriptorVec {
pub fn close_on_exec(&mut self) { pub fn close_on_exec(&mut self) {
for i in 0..FileDescriptorVec::PROCESS_MAX_FD { for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
if let Some(file) = &self.fds[i] { if let Some(file) = &self.fds[i] {
let to_drop = file.lock().close_on_exec(); let to_drop = file.close_on_exec();
if to_drop { if to_drop {
if let Err(r) = self.drop_fd(i as i32) { if let Err(r) = self.drop_fd(i as i32) {
kerror!( kerror!(
@ -670,7 +685,7 @@ impl<'a> FileDescriptorIterator<'a> {
} }
impl<'a> Iterator for FileDescriptorIterator<'a> { impl<'a> Iterator for FileDescriptorIterator<'a> {
type Item = (i32, Arc<SpinLock<File>>); type Item = (i32, Arc<File>);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
while self.index < FileDescriptorVec::PROCESS_MAX_FD { while self.index < FileDescriptorVec::PROCESS_MAX_FD {

View File

@ -8,6 +8,7 @@ mod utils;
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize}; use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
use alloc::{string::String, sync::Arc, vec::Vec}; use alloc::{string::String, sync::Arc, vec::Vec};
use intertrait::CastFromSync;
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
@ -15,7 +16,10 @@ use crate::{
block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber, block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber,
}, },
ipc::pipe::LockedPipeInode, ipc::pipe::LockedPipeInode,
libs::casting::DowncastArc, libs::{
casting::DowncastArc,
spinlock::{SpinLock, SpinLockGuard},
},
time::TimeSpec, time::TimeSpec,
}; };
@ -114,12 +118,16 @@ bitflags! {
} }
} }
pub trait IndexNode: Any + Sync + Send + Debug { pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
/// @brief 打开文件 /// @brief 打开文件
/// ///
/// @return 成功Ok() /// @return 成功Ok()
/// 失败Err(错误码) /// 失败Err(错误码)
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持” // 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
} }
@ -128,7 +136,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
/// ///
/// @return 成功Ok() /// @return 成功Ok()
/// 失败Err(错误码) /// 失败Err(错误码)
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持” // 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
} }
@ -147,7 +155,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError>; ) -> Result<usize, SystemError>;
/// @brief 在inode的指定偏移量开始写入指定大小的数据从buf的第0byte开始写入 /// @brief 在inode的指定偏移量开始写入指定大小的数据从buf的第0byte开始写入
@ -164,7 +172,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError>; ) -> Result<usize, SystemError>;
/// @brief 获取当前inode的状态。 /// @brief 获取当前inode的状态。
@ -494,7 +502,12 @@ impl dyn IndexNode {
if inode.metadata()?.file_type == FileType::SymLink && max_follow_times > 0 { if inode.metadata()?.file_type == FileType::SymLink && max_follow_times > 0 {
let mut content = [0u8; 256]; let mut content = [0u8; 256];
// 读取符号链接 // 读取符号链接
let len = inode.read_at(0, 256, &mut content, &mut FilePrivateData::Unused)?; let len = inode.read_at(
0,
256,
&mut content,
SpinLock::new(FilePrivateData::Unused).lock(),
)?;
// 将读到的数据转换为utf8字符串先转为str再转为String // 将读到的数据转换为utf8字符串先转为str再转为String
let link_path = String::from( let link_path = String::from(

View File

@ -9,7 +9,10 @@ use alloc::{
}; };
use system_error::SystemError; use system_error::SystemError;
use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::SpinLock}; use crate::{
driver::base::device::device_number::DeviceNumber,
libs::spinlock::{SpinLock, SpinLockGuard},
};
use super::{ use super::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
@ -34,6 +37,7 @@ pub struct MountFS {
/// @brief MountFS的Index Node 注意这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。 /// @brief MountFS的Index Node 注意这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
#[derive(Debug)] #[derive(Debug)]
#[cast_to([sync] IndexNode)]
pub struct MountFSInode { pub struct MountFSInode {
/// 当前挂载点对应到具体的文件系统的Inode /// 当前挂载点对应到具体的文件系统的Inode
inner_inode: Arc<dyn IndexNode>, inner_inode: Arc<dyn IndexNode>,
@ -88,6 +92,10 @@ impl MountFS {
pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> { pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
return self.inner_filesystem.clone(); return self.inner_filesystem.clone();
} }
pub fn self_ref(&self) -> Arc<Self> {
self.self_ref.upgrade().unwrap()
}
} }
impl MountFSInode { impl MountFSInode {
@ -132,14 +140,37 @@ impl MountFSInode {
return self.self_ref.upgrade().unwrap(); return self.self_ref.upgrade().unwrap();
} }
} }
/// 将新的挂载点-挂载文件系统添加到父级的挂载树
pub(super) fn do_mount(
&self,
inode_id: InodeId,
new_mount_fs: Arc<MountFS>,
) -> Result<(), SystemError> {
let mut guard = self.mount_fs.mountpoints.lock();
if guard.contains_key(&inode_id) {
return Err(SystemError::EBUSY);
}
guard.insert(inode_id, new_mount_fs);
return Ok(());
}
pub(super) fn inode_id(&self) -> InodeId {
self.metadata().map(|x| x.inode_id).unwrap()
}
} }
impl IndexNode for MountFSInode { impl IndexNode for MountFSInode {
fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
data: SpinLockGuard<FilePrivateData>,
mode: &FileMode,
) -> Result<(), SystemError> {
return self.inner_inode.open(data, mode); return self.inner_inode.open(data, mode);
} }
fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return self.inner_inode.close(data); return self.inner_inode.close(data);
} }
@ -169,7 +200,7 @@ impl IndexNode for MountFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return self.inner_inode.read_at(offset, len, buf, data); return self.inner_inode.read_at(offset, len, buf, data);
} }
@ -179,7 +210,7 @@ impl IndexNode for MountFSInode {
offset: usize, offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
return self.inner_inode.write_at(offset, len, buf, data); return self.inner_inode.write_at(offset, len, buf, data);
} }
@ -345,11 +376,7 @@ impl IndexNode for MountFSInode {
// 为新的挂载点创建挂载文件系统 // 为新的挂载点创建挂载文件系统
let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap())); let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap()));
// 将新的挂载点-挂载文件系统添加到父级的挂载树 self.do_mount(metadata.inode_id, new_mount_fs.clone())?;
self.mount_fs
.mountpoints
.lock()
.insert(metadata.inode_id, new_mount_fs.clone());
return Ok(new_mount_fs); return Ok(new_mount_fs);
} }

View File

@ -123,7 +123,7 @@ fn do_sys_openat2(
// 创建文件对象 // 创建文件对象
let mut file: File = File::new(inode, how.o_flags)?; let file: File = File::new(inode, how.o_flags)?;
// 打开模式为“追加” // 打开模式为“追加”
if how.o_flags.contains(FileMode::O_APPEND) { if how.o_flags.contains(FileMode::O_APPEND) {

View File

@ -519,8 +519,7 @@ impl Syscall {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
let file = file.lock_no_preempt(); let r = file.inode().ioctl(cmd, data, &file.private_data.lock());
let r = file.inode().ioctl(cmd, data, &file.private_data);
return r; return r;
} }
@ -543,7 +542,7 @@ impl Syscall {
drop(fd_table_guard); drop(fd_table_guard);
let file = file.unwrap(); let file = file.unwrap();
return file.lock_no_preempt().read(buf.len(), buf); return file.read(buf.len(), buf);
} }
/// @brief 根据文件描述符向文件写入数据。尝试写入的数据长度与buf的长度相同。 /// @brief 根据文件描述符向文件写入数据。尝试写入的数据长度与buf的长度相同。
@ -563,7 +562,7 @@ impl Syscall {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
return file.lock_no_preempt().write(buf.len(), buf); return file.write(buf.len(), buf);
} }
/// @brief 调整文件操作指针的位置 /// @brief 调整文件操作指针的位置
@ -590,7 +589,7 @@ impl Syscall {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
return file.lock_no_preempt().lseek(seek); return file.lseek(seek);
} }
/// # sys_pread64 系统调用的实际执行函数 /// # sys_pread64 系统调用的实际执行函数
@ -612,7 +611,7 @@ impl Syscall {
drop(fd_table_guard); drop(fd_table_guard);
let file = file.unwrap(); let file = file.unwrap();
return file.lock_no_preempt().pread(offset, len, buf); return file.pread(offset, len, buf);
} }
/// # sys_pwrite64 系统调用的实际执行函数 /// # sys_pwrite64 系统调用的实际执行函数
@ -634,7 +633,7 @@ impl Syscall {
drop(fd_table_guard); drop(fd_table_guard);
let file = file.unwrap(); let file = file.unwrap();
return file.lock_no_preempt().pwrite(offset, len, buf); return file.pwrite(offset, len, buf);
} }
/// @brief 切换工作目录 /// @brief 切换工作目录
@ -757,7 +756,7 @@ impl Syscall {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
let res = file.lock_no_preempt().readdir(dirent).map(|x| x as usize); let res = file.readdir(dirent).map(|x| x as usize);
return res; return res;
} }
@ -811,7 +810,7 @@ impl Syscall {
let file = fd_table_guard let file = fd_table_guard
.get_file_by_fd(oldfd) .get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
let old_inode = file.lock().inode(); let old_inode = file.inode();
old_inode old_inode
} else { } else {
return Err(SystemError::ENONET); return Err(SystemError::ENONET);
@ -978,10 +977,7 @@ impl Syscall {
.get_file_by_fd(oldfd) .get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
let new_file = old_file let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
.lock_no_preempt()
.try_clone()
.ok_or(SystemError::EBADF)?;
// 申请文件描述符,并把文件对象存入其中 // 申请文件描述符,并把文件对象存入其中
let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize);
return res; return res;
@ -1032,10 +1028,7 @@ impl Syscall {
let old_file = fd_table_guard let old_file = fd_table_guard
.get_file_by_fd(oldfd) .get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
let new_file = old_file let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
.lock_no_preempt()
.try_clone()
.ok_or(SystemError::EBADF)?;
// 申请文件描述符,并把文件对象存入其中 // 申请文件描述符,并把文件对象存入其中
let res = fd_table_guard let res = fd_table_guard
.alloc_fd(new_file, Some(newfd)) .alloc_fd(new_file, Some(newfd))
@ -1074,7 +1067,7 @@ impl Syscall {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
if file.lock().close_on_exec() { if file.close_on_exec() {
return Ok(FD_CLOEXEC as usize); return Ok(FD_CLOEXEC as usize);
} }
} }
@ -1090,9 +1083,9 @@ impl Syscall {
drop(fd_table_guard); drop(fd_table_guard);
let arg = arg as u32; let arg = arg as u32;
if arg & FD_CLOEXEC != 0 { if arg & FD_CLOEXEC != 0 {
file.lock().set_close_on_exec(true); file.set_close_on_exec(true);
} else { } else {
file.lock().set_close_on_exec(false); file.set_close_on_exec(false);
} }
return Ok(0); return Ok(0);
} }
@ -1107,7 +1100,7 @@ impl Syscall {
if let Some(file) = fd_table_guard.get_file_by_fd(fd) { if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
return Ok(file.lock_no_preempt().mode().bits() as usize); return Ok(file.mode().bits() as usize);
} }
return Err(SystemError::EBADF); return Err(SystemError::EBADF);
@ -1122,7 +1115,7 @@ impl Syscall {
let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?; let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?;
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
file.lock_no_preempt().set_mode(mode)?; file.set_mode(mode)?;
return Ok(0); return Ok(0);
} }
@ -1161,7 +1154,7 @@ impl Syscall {
if let Some(file) = fd_table_guard.get_file_by_fd(fd) { if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
let r = file.lock_no_preempt().ftruncate(len).map(|_| 0); let r = file.ftruncate(len).map(|_| 0);
return r; return r;
} }
@ -1179,7 +1172,7 @@ impl Syscall {
let mut kstat = PosixKstat::new(); let mut kstat = PosixKstat::new();
// 获取文件信息 // 获取文件信息
let metadata = file.lock().metadata()?; let metadata = file.metadata()?;
kstat.size = metadata.size; kstat.size = metadata.size;
kstat.dev_id = metadata.dev_id as u64; kstat.dev_id = metadata.dev_id as u64;
kstat.inode = metadata.inode_id.into() as u64; kstat.inode = metadata.inode_id.into() as u64;
@ -1198,7 +1191,7 @@ impl Syscall {
kstat.gid = metadata.gid as i32; kstat.gid = metadata.gid as i32;
kstat.rdev = metadata.raw_dev.data() as i64; kstat.rdev = metadata.raw_dev.data() as i64;
kstat.mode = metadata.mode; kstat.mode = metadata.mode;
match file.lock().file_type() { match file.file_type() {
FileType::File => kstat.mode.insert(ModeType::S_IFREG), FileType::File => kstat.mode.insert(ModeType::S_IFREG),
FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK),
@ -1270,7 +1263,7 @@ impl Syscall {
.get_file_by_fd(fd) .get_file_by_fd(fd)
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
drop(fd_table_guard); drop(fd_table_guard);
let statfs = PosixStatfs::from(file.lock().inode().fs().super_block()); let statfs = PosixStatfs::from(file.inode().fs().super_block());
writer.copy_one_to_user(&statfs, 0)?; writer.copy_one_to_user(&statfs, 0)?;
return Ok(0); return Ok(0);
} }
@ -1305,7 +1298,7 @@ impl Syscall {
let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?; let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?;
let mut tmp: PosixStatx = PosixStatx::new(); let mut tmp: PosixStatx = PosixStatx::new();
// 获取文件信息 // 获取文件信息
let metadata = file.lock().metadata()?; let metadata = file.metadata()?;
tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS; tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS;
tmp.stx_blksize = metadata.blk_size as u32; tmp.stx_blksize = metadata.blk_size as u32;
@ -1366,7 +1359,7 @@ impl Syscall {
tmp.stx_dio_offset_align = 0; tmp.stx_dio_offset_align = 0;
} }
match file.lock().file_type() { match file.file_type() {
FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG), FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG),
FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR), FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR),
FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK), FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK),
@ -1450,7 +1443,7 @@ impl Syscall {
let ubuf = user_buf.buffer::<u8>(0).unwrap(); let ubuf = user_buf.buffer::<u8>(0).unwrap();
let mut file = File::new(inode, FileMode::O_RDONLY)?; let file = File::new(inode, FileMode::O_RDONLY)?;
let len = file.read(buf_size, ubuf)?; let len = file.read(buf_size, ubuf)?;

View File

@ -53,13 +53,12 @@ pub fn user_path_at(
// drop guard 以避免无法调度的问题 // drop guard 以避免无法调度的问题
drop(fd_table_guard); drop(fd_table_guard);
let file_guard = file.lock();
// 如果dirfd不是目录则返回错误码ENOTDIR // 如果dirfd不是目录则返回错误码ENOTDIR
if file_guard.file_type() != FileType::Dir { if file.file_type() != FileType::Dir {
return Err(SystemError::ENOTDIR); return Err(SystemError::ENOTDIR);
} }
inode = file_guard.inode(); inode = file.inode();
ret_path = String::from(path); ret_path = String::from(path);
} else { } else {
let mut cwd = pcb.basic().cwd(); let mut cwd = pcb.basic().cwd();

View File

@ -5,7 +5,10 @@ use crate::{
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
FileType, IndexNode, Metadata, FileType, IndexNode, Metadata,
}, },
libs::{spinlock::SpinLock, wait_queue::WaitQueue}, libs::{
spinlock::{SpinLock, SpinLockGuard},
wait_queue::WaitQueue,
},
net::event_poll::{EPollEventType, EPollItem, EventPoll}, net::event_poll::{EPollEventType, EPollItem, EventPoll},
process::ProcessState, process::ProcessState,
time::TimeSpec, time::TimeSpec,
@ -37,7 +40,11 @@ impl PipeFsPrivateData {
/// @brief 管道文件i节点(锁) /// @brief 管道文件i节点(锁)
#[derive(Debug)] #[derive(Debug)]
pub struct LockedPipeInode(SpinLock<InnerPipeInode>); pub struct LockedPipeInode {
inner: SpinLock<InnerPipeInode>,
read_wait_queue: WaitQueue,
write_wait_queue: WaitQueue,
}
/// @brief 管道文件i节点(无锁) /// @brief 管道文件i节点(无锁)
#[derive(Debug)] #[derive(Debug)]
@ -47,8 +54,6 @@ pub struct InnerPipeInode {
valid_cnt: i32, valid_cnt: i32,
read_pos: i32, read_pos: i32,
write_pos: i32, write_pos: i32,
read_wait_queue: WaitQueue,
write_wait_queue: WaitQueue,
data: [u8; PIPE_BUFF_SIZE], data: [u8; PIPE_BUFF_SIZE],
/// INode 元数据 /// INode 元数据
metadata: Metadata, metadata: Metadata,
@ -107,8 +112,6 @@ impl LockedPipeInode {
valid_cnt: 0, valid_cnt: 0,
read_pos: 0, read_pos: 0,
write_pos: 0, write_pos: 0,
read_wait_queue: WaitQueue::default(),
write_wait_queue: WaitQueue::default(),
data: [0; PIPE_BUFF_SIZE], data: [0; PIPE_BUFF_SIZE],
metadata: Metadata { metadata: Metadata {
@ -131,8 +134,12 @@ impl LockedPipeInode {
writer: 0, writer: 0,
epitems: SpinLock::new(LinkedList::new()), epitems: SpinLock::new(LinkedList::new()),
}; };
let result = Arc::new(Self(SpinLock::new(inner))); let result = Arc::new(Self {
let mut guard = result.0.lock(); inner: SpinLock::new(inner),
read_wait_queue: WaitQueue::default(),
write_wait_queue: WaitQueue::default(),
});
let mut guard = result.inner.lock();
guard.self_ref = Arc::downgrade(&result); guard.self_ref = Arc::downgrade(&result);
// 释放锁 // 释放锁
drop(guard); //这一步其实不需要只要离开作用域guard生命周期结束自会解锁 drop(guard); //这一步其实不需要只要离开作用域guard生命周期结束自会解锁
@ -140,7 +147,7 @@ impl LockedPipeInode {
} }
pub fn inner(&self) -> &SpinLock<InnerPipeInode> { pub fn inner(&self) -> &SpinLock<InnerPipeInode> {
&self.0 &self.inner
} }
} }
@ -150,11 +157,11 @@ impl IndexNode for LockedPipeInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
// 获取mode // 获取mode
let mode: FileMode; let mode: FileMode;
if let FilePrivateData::Pipefs(pdata) = data { if let FilePrivateData::Pipefs(pdata) = &*data {
mode = pdata.mode; mode = pdata.mode;
} else { } else {
return Err(SystemError::EBADF); return Err(SystemError::EBADF);
@ -164,7 +171,7 @@ impl IndexNode for LockedPipeInode {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
} }
// 加锁 // 加锁
let mut inode = self.0.lock(); let mut inode = self.inner.lock();
// 如果管道里面没有数据,则唤醒写端, // 如果管道里面没有数据,则唤醒写端,
while inode.valid_cnt == 0 { while inode.valid_cnt == 0 {
@ -173,8 +180,7 @@ impl IndexNode for LockedPipeInode {
return Ok(0); return Ok(0);
} }
inode self.write_wait_queue
.write_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
// 如果为非阻塞管道,直接返回错误 // 如果为非阻塞管道,直接返回错误
@ -187,13 +193,12 @@ impl IndexNode for LockedPipeInode {
unsafe { unsafe {
let irq_guard = CurrentIrqArch::save_and_disable_irq(); let irq_guard = CurrentIrqArch::save_and_disable_irq();
inode.read_wait_queue.sleep_without_schedule();
drop(inode); drop(inode);
self.read_wait_queue.sleep_without_schedule();
drop(irq_guard); drop(irq_guard);
} }
sched(); sched();
inode = self.0.lock(); inode = self.inner.lock();
} }
let mut num = inode.valid_cnt as usize; let mut num = inode.valid_cnt as usize;
@ -222,17 +227,15 @@ impl IndexNode for LockedPipeInode {
// 读完以后如果未读完,则唤醒下一个读者 // 读完以后如果未读完,则唤醒下一个读者
if inode.valid_cnt > 0 { if inode.valid_cnt > 0 {
inode self.read_wait_queue
.read_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
} }
//读完后解锁并唤醒等待在写等待队列中的进程 //读完后解锁并唤醒等待在写等待队列中的进程
inode self.write_wait_queue
.write_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
let pollflag = EPollEventType::from_bits_truncate(inode.poll(data)? as u32); let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
// 唤醒epoll中等待的进程 // 唤醒epoll中等待的进程
EventPoll::wakeup_epoll(&inode.epitems, pollflag)?; EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
@ -242,10 +245,10 @@ impl IndexNode for LockedPipeInode {
fn open( fn open(
&self, &self,
data: &mut FilePrivateData, mut data: SpinLockGuard<FilePrivateData>,
mode: &crate::filesystem::vfs::file::FileMode, mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
let mut guard = self.0.lock(); let mut guard = self.inner.lock();
// 不能以读写方式打开管道 // 不能以读写方式打开管道
if mode.contains(FileMode::O_RDWR) { if mode.contains(FileMode::O_RDWR) {
return Err(SystemError::EACCES); return Err(SystemError::EACCES);
@ -264,21 +267,21 @@ impl IndexNode for LockedPipeInode {
} }
fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
let inode = self.0.lock(); let inode = self.inner.lock();
let mut metadata = inode.metadata.clone(); let mut metadata = inode.metadata.clone();
metadata.size = inode.data.len() as i64; metadata.size = inode.data.len() as i64;
return Ok(metadata); return Ok(metadata);
} }
fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let mode: FileMode; let mode: FileMode;
if let FilePrivateData::Pipefs(pipe_data) = data { if let FilePrivateData::Pipefs(pipe_data) = &*data {
mode = pipe_data.mode; mode = pipe_data.mode;
} else { } else {
return Err(SystemError::EBADF); return Err(SystemError::EBADF);
} }
let mut guard = self.0.lock(); let mut guard = self.inner.lock();
// 写端关闭 // 写端关闭
if mode.contains(FileMode::O_WRONLY) { if mode.contains(FileMode::O_WRONLY) {
@ -286,8 +289,7 @@ impl IndexNode for LockedPipeInode {
guard.writer -= 1; guard.writer -= 1;
// 如果已经没有写端了,则唤醒读端 // 如果已经没有写端了,则唤醒读端
if guard.writer == 0 { if guard.writer == 0 {
guard self.read_wait_queue
.read_wait_queue
.wakeup_all(Some(ProcessState::Blocked(true))); .wakeup_all(Some(ProcessState::Blocked(true)));
} }
} }
@ -298,8 +300,7 @@ impl IndexNode for LockedPipeInode {
guard.reader -= 1; guard.reader -= 1;
// 如果已经没有写端了,则唤醒读端 // 如果已经没有写端了,则唤醒读端
if guard.reader == 0 { if guard.reader == 0 {
guard self.write_wait_queue
.write_wait_queue
.wakeup_all(Some(ProcessState::Blocked(true))); .wakeup_all(Some(ProcessState::Blocked(true)));
} }
} }
@ -312,11 +313,11 @@ impl IndexNode for LockedPipeInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
data: &mut FilePrivateData, data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
// 获取mode // 获取mode
let mode: FileMode; let mode: FileMode;
if let FilePrivateData::Pipefs(pdata) = data { if let FilePrivateData::Pipefs(pdata) = &*data {
mode = pdata.mode; mode = pdata.mode;
} else { } else {
return Err(SystemError::EBADF); return Err(SystemError::EBADF);
@ -327,7 +328,7 @@ impl IndexNode for LockedPipeInode {
} }
// 加锁 // 加锁
let mut inode = self.0.lock(); let mut inode = self.inner.lock();
if inode.reader == 0 { if inode.reader == 0 {
// TODO: 如果已经没有读端存在了则向写端进程发送SIGPIPE信号 // TODO: 如果已经没有读端存在了则向写端进程发送SIGPIPE信号
@ -337,8 +338,7 @@ impl IndexNode for LockedPipeInode {
while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE { while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE {
// 唤醒读端 // 唤醒读端
inode self.read_wait_queue
.read_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
// 如果为非阻塞管道,直接返回错误 // 如果为非阻塞管道,直接返回错误
@ -350,12 +350,12 @@ impl IndexNode for LockedPipeInode {
// 解锁并睡眠 // 解锁并睡眠
unsafe { unsafe {
let irq_guard = CurrentIrqArch::save_and_disable_irq(); let irq_guard = CurrentIrqArch::save_and_disable_irq();
inode.write_wait_queue.sleep_without_schedule();
drop(inode); drop(inode);
self.write_wait_queue.sleep_without_schedule();
drop(irq_guard); drop(irq_guard);
} }
sched(); sched();
inode = self.0.lock(); inode = self.inner.lock();
} }
// 决定要输入的字节 // 决定要输入的字节
@ -375,17 +375,15 @@ impl IndexNode for LockedPipeInode {
// 写完后还有位置,则唤醒下一个写者 // 写完后还有位置,则唤醒下一个写者
if (inode.valid_cnt as usize) < PIPE_BUFF_SIZE { if (inode.valid_cnt as usize) < PIPE_BUFF_SIZE {
inode self.write_wait_queue
.write_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
} }
// 读完后解锁并唤醒等待在读等待队列中的进程 // 读完后解锁并唤醒等待在读等待队列中的进程
inode self.read_wait_queue
.read_wait_queue
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
let pollflag = EPollEventType::from_bits_truncate(inode.poll(data)? as u32); let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
// 唤醒epoll中等待的进程 // 唤醒epoll中等待的进程
EventPoll::wakeup_epoll(&inode.epitems, pollflag)?; EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
@ -416,6 +414,6 @@ impl IndexNode for LockedPipeInode {
} }
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> { fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
return self.0.lock().poll(private_data); return self.inner.lock().poll(private_data);
} }
} }

View File

@ -12,6 +12,7 @@ use crate::{
FilePrivateData, FilePrivateData,
}, },
kerror, kwarn, kerror, kwarn,
libs::spinlock::SpinLock,
mm::VirtAddr, mm::VirtAddr,
process::{Pid, ProcessManager}, process::{Pid, ProcessManager},
syscall::{user_access::UserBufferWriter, Syscall}, syscall::{user_access::UserBufferWriter, Syscall},
@ -48,16 +49,17 @@ impl Syscall {
pipe_ptr.clone(), pipe_ptr.clone(),
FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK), FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
)?; )?;
read_file.private_data = read_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
FilePrivateData::Pipefs(PipeFsPrivateData::new(FileMode::O_RDONLY)); FileMode::O_RDONLY,
)));
let mut write_file = File::new( let mut write_file = File::new(
pipe_ptr.clone(), pipe_ptr.clone(),
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)), FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
)?; )?;
write_file.private_data = FilePrivateData::Pipefs(PipeFsPrivateData::new( write_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)), FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
)); )));
if flags.contains(FileMode::O_CLOEXEC) { if flags.contains(FileMode::O_CLOEXEC) {
read_file.set_close_on_exec(true); read_file.set_close_on_exec(true);

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
driver::{ driver::{
serial::serial8250::send_to_default_serial8250_port, serial::serial8250::send_to_default_serial8250_port,
tty::{tty_port::TTY_PORTS, virtual_terminal::virtual_console::CURRENT_VCNUM}, tty::{tty_port::tty_port, virtual_terminal::virtual_console::CURRENT_VCNUM},
video::video_refresh_manager, video::video_refresh_manager,
}, },
kdebug, kinfo, kdebug, kinfo,
@ -1046,8 +1046,8 @@ pub extern "C" fn rs_textui_putchar(character: u8, fr_color: u32, bk_color: u32)
"\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{}\x1B[0m", "\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{}\x1B[0m",
character as char character as char
); );
let port = TTY_PORTS[current_vcnum as usize].clone(); let port = tty_port(current_vcnum as usize);
let tty = port.port_data().tty(); let tty = port.port_data().internal_tty();
if let Some(tty) = tty { if let Some(tty) = tty {
send_to_default_serial8250_port(&[character]); send_to_default_serial8250_port(&[character]);
return tty return tty

View File

@ -9,7 +9,7 @@ use super::lib_ui::textui::{textui_putstr, FontColor};
use crate::{ use crate::{
driver::tty::{ driver::tty::{
tty_driver::TtyOperation, tty_port::TTY_PORTS, tty_driver::TtyOperation, tty_port::tty_port,
virtual_terminal::virtual_console::CURRENT_VCNUM, virtual_terminal::virtual_console::CURRENT_VCNUM,
}, },
filesystem::procfs::{ filesystem::procfs::{
@ -89,8 +89,8 @@ impl PrintkWriter {
let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst); let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
if current_vcnum != -1 { if current_vcnum != -1 {
// tty已经初始化了之后才输出到屏幕 // tty已经初始化了之后才输出到屏幕
let port = TTY_PORTS[current_vcnum as usize].clone(); let port = tty_port(current_vcnum as usize);
let tty = port.port_data().tty(); let tty = port.port_data().internal_tty();
if let Some(tty) = tty { if let Some(tty) = tty {
let _ = tty.write(tty.core(), s.as_bytes(), s.len()); let _ = tty.write(tty.core(), s.as_bytes(), s.len());
} else { } else {

View File

@ -278,11 +278,17 @@ pub struct EventWaitQueue {
wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>, wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
} }
impl Default for EventWaitQueue {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)] #[allow(dead_code)]
impl EventWaitQueue { impl EventWaitQueue {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
wait_list: SpinLock::new(Vec::new()), wait_list: SpinLock::new(Default::default()),
} }
} }

View File

@ -82,7 +82,7 @@ pub struct EPollItem {
/// 监听的描述符 /// 监听的描述符
fd: i32, fd: i32,
/// 对应的文件 /// 对应的文件
file: Weak<SpinLock<File>>, file: Weak<File>,
} }
impl EPollItem { impl EPollItem {
@ -90,7 +90,7 @@ impl EPollItem {
epoll: Weak<SpinLock<EventPoll>>, epoll: Weak<SpinLock<EventPoll>>,
events: EPollEvent, events: EPollEvent,
fd: i32, fd: i32,
file: Weak<SpinLock<File>>, file: Weak<File>,
) -> Self { ) -> Self {
Self { Self {
epoll, epoll,
@ -108,7 +108,7 @@ impl EPollItem {
&self.event &self.event
} }
pub fn file(&self) -> Weak<SpinLock<File>> { pub fn file(&self) -> Weak<File> {
self.file.clone() self.file.clone()
} }
@ -122,7 +122,7 @@ impl EPollItem {
if file.is_none() { if file.is_none() {
return EPollEventType::empty(); return EPollEventType::empty();
} }
if let Ok(events) = file.unwrap().lock_irqsave().poll() { if let Ok(events) = file.unwrap().poll() {
let events = events as u32 & self.event.read().events; let events = events as u32 & self.event.read().events;
return EPollEventType::from_bits_truncate(events); return EPollEventType::from_bits_truncate(events);
} }
@ -154,7 +154,7 @@ impl IndexNode for EPollInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut crate::filesystem::vfs::FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS) Err(SystemError::ENOSYS)
} }
@ -164,7 +164,7 @@ impl IndexNode for EPollInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut crate::filesystem::vfs::FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS) Err(SystemError::ENOSYS)
} }
@ -190,7 +190,7 @@ impl IndexNode for EPollInode {
Ok(Metadata::default()) Ok(Metadata::default())
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// 释放资源 // 释放资源
let mut epoll = self.epoll.0.lock_irqsave(); let mut epoll = self.epoll.0.lock_irqsave();
@ -208,9 +208,7 @@ impl IndexNode for EPollInode {
.get_file_by_fd(fd); .get_file_by_fd(fd);
if file.is_some() { if file.is_some() {
file.unwrap() file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?;
.lock_irqsave()
.remove_epoll(&Arc::downgrade(&self.epoll.0))?;
} }
epoll.ep_items.remove(&fd); epoll.ep_items.remove(&fd);
@ -219,7 +217,11 @@ impl IndexNode for EPollInode {
Ok(()) Ok(())
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(()) Ok(())
} }
} }
@ -250,7 +252,7 @@ impl EventPoll {
)?; )?;
// 设置ep_file的FilePrivateData // 设置ep_file的FilePrivateData
ep_file.private_data = FilePrivateData::EPoll(EPollPrivateData { epoll }); ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll }));
let current_pcb = ProcessManager::current_pcb(); let current_pcb = ProcessManager::current_pcb();
let fd_table = current_pcb.fd_table(); let fd_table = current_pcb.fd_table();
@ -321,7 +323,7 @@ impl EventPoll {
} }
// 从FilePrivateData获取到epoll // 从FilePrivateData获取到epoll
if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data { if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
let mut epoll_guard = { let mut epoll_guard = {
if nonblock { if nonblock {
// 如果设置非阻塞,则尝试获取一次锁 // 如果设置非阻塞,则尝试获取一次锁
@ -412,7 +414,7 @@ impl EventPoll {
// 从epoll文件获取到epoll // 从epoll文件获取到epoll
let mut epolldata = None; let mut epolldata = None;
if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data { if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
epolldata = Some(epoll_data.clone()) epolldata = Some(epoll_data.clone())
} }
if let Some(epoll_data) = epolldata { if let Some(epoll_data) = epolldata {
@ -583,8 +585,8 @@ impl EventPoll {
} }
// ### 查看文件是否为epoll文件 // ### 查看文件是否为epoll文件
fn is_epoll_file(file: &Arc<SpinLock<File>>) -> bool { fn is_epoll_file(file: &Arc<File>) -> bool {
if let FilePrivateData::EPoll(_) = file.lock_irqsave().private_data { if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
return true; return true;
} }
return false; return false;
@ -592,7 +594,7 @@ impl EventPoll {
fn ep_insert( fn ep_insert(
epoll_guard: &mut SpinLockGuard<EventPoll>, epoll_guard: &mut SpinLockGuard<EventPoll>,
dst_file: Arc<SpinLock<File>>, dst_file: Arc<File>,
epitem: Arc<EPollItem>, epitem: Arc<EPollItem>,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
if Self::is_epoll_file(&dst_file) { if Self::is_epoll_file(&dst_file) {
@ -600,7 +602,7 @@ impl EventPoll {
// TODO现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll // TODO现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll
} }
let test_poll = dst_file.lock_irqsave().poll(); let test_poll = dst_file.poll();
if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP { if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
// 如果目标文件不支持poll // 如果目标文件不支持poll
return Err(SystemError::ENOSYS); return Err(SystemError::ENOSYS);
@ -624,19 +626,17 @@ impl EventPoll {
return Err(SystemError::ENOSYS); return Err(SystemError::ENOSYS);
} }
dst_file.lock_irqsave().add_epoll(epitem.clone())?; dst_file.add_epoll(epitem.clone())?;
Ok(()) Ok(())
} }
pub fn ep_remove( pub fn ep_remove(
epoll: &mut SpinLockGuard<EventPoll>, epoll: &mut SpinLockGuard<EventPoll>,
fd: i32, fd: i32,
dst_file: Option<Arc<SpinLock<File>>>, dst_file: Option<Arc<File>>,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
if let Some(dst_file) = dst_file { if let Some(dst_file) = dst_file {
let mut file_guard = dst_file.lock_irqsave(); dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
file_guard.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
} }
let epitem = epoll.ep_items.remove(&fd).unwrap(); let epitem = epoll.ep_items.remove(&fd).unwrap();

View File

@ -299,12 +299,16 @@ impl SocketInode {
} }
impl IndexNode for SocketInode { impl IndexNode for SocketInode {
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst); self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
Ok(()) Ok(())
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst); let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
if prev_ref_count == 1 { if prev_ref_count == 1 {
// 最后一次关闭,需要释放 // 最后一次关闭,需要释放
@ -333,7 +337,7 @@ impl IndexNode for SocketInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &mut [u8], buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
self.0.lock_no_preempt().read(&mut buf[0..len]).0 self.0.lock_no_preempt().read(&mut buf[0..len]).0
} }
@ -343,7 +347,7 @@ impl IndexNode for SocketInode {
_offset: usize, _offset: usize,
len: usize, len: usize,
buf: &[u8], buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
self.0.lock_no_preempt().write(&buf[0..len], None) self.0.lock_no_preempt().write(&buf[0..len], None)
} }

View File

@ -603,8 +603,7 @@ impl SockAddr {
let binding = ProcessManager::current_pcb().fd_table(); let binding = ProcessManager::current_pcb().fd_table();
let fd_table_guard = binding.read(); let fd_table_guard = binding.read();
let binding = fd_table_guard.get_file_by_fd(fd as i32).unwrap(); let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
let file = binding.lock();
if file.file_type() != FileType::Socket { if file.file_type() != FileType::Socket {
return Err(SystemError::ENOTSOCK); return Err(SystemError::ENOTSOCK);
} }

View File

@ -822,11 +822,10 @@ impl ProcessControlBlock {
let f = fd_table_guard.get_file_by_fd(fd)?; let f = fd_table_guard.get_file_by_fd(fd)?;
drop(fd_table_guard); drop(fd_table_guard);
let guard = f.lock(); if f.file_type() != FileType::Socket {
if guard.file_type() != FileType::Socket {
return None; return None;
} }
let socket: Arc<SocketInode> = guard let socket: Arc<SocketInode> = f
.inode() .inode()
.downcast_arc::<SocketInode>() .downcast_arc::<SocketInode>()
.expect("Not a socket inode"); .expect("Not a socket inode");

View File

@ -862,6 +862,10 @@ impl Syscall {
kwarn!("SYS_SETGID has not yet been implemented"); kwarn!("SYS_SETGID has not yet been implemented");
Ok(0) Ok(0)
} }
SYS_SETSID => {
kwarn!("SYS_SETSID has not yet been implemented");
Ok(0)
}
SYS_GETEUID => Self::geteuid(), SYS_GETEUID => Self::geteuid(),
SYS_GETEGID => Self::getegid(), SYS_GETEGID => Self::getegid(),
SYS_GETRUSAGE => { SYS_GETRUSAGE => {
@ -944,6 +948,16 @@ impl Syscall {
Ok(0) Ok(0)
} }
SYS_SET_ROBUST_LIST => {
kwarn!("SYS_SET_ROBUST_LIST has not yet been implemented");
Ok(0)
}
SYS_RSEQ => {
kwarn!("SYS_RSEQ has not yet been implemented");
Ok(0)
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
SYS_CHMOD => { SYS_CHMOD => {
let pathname = args[0] as *const u8; let pathname = args[0] as *const u8;

View File

@ -5,6 +5,7 @@ use crate::filesystem::vfs::{
file::{File, FileMode}, file::{File, FileMode},
FilePrivateData, FileSystem, FileType, IndexNode, Metadata, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::process::ProcessManager; use crate::process::ProcessManager;
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec}; use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
use crate::{filesystem, kdebug}; use crate::{filesystem, kdebug};
@ -88,12 +89,16 @@ impl IndexNode for LockedKvmInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
kdebug!("file private data:{:?}", _data); kdebug!("file private data:{:?}", _data);
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -158,7 +163,7 @@ impl IndexNode for LockedKvmInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }
@ -169,7 +174,7 @@ impl IndexNode for LockedKvmInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }

View File

@ -6,6 +6,7 @@ use crate::filesystem::vfs::{
core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::mm::VirtAddr; use crate::mm::VirtAddr;
use crate::syscall::user_access::copy_from_user; use crate::syscall::user_access::copy_from_user;
use crate::virt::kvm::vcpu::Vcpu; use crate::virt::kvm::vcpu::Vcpu;
@ -96,12 +97,16 @@ impl IndexNode for LockedVcpuInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
kdebug!("file private data:{:?}", _data); kdebug!("file private data:{:?}", _data);
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -197,7 +202,7 @@ impl IndexNode for LockedVcpuInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }
@ -208,7 +213,7 @@ impl IndexNode for LockedVcpuInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }

View File

@ -5,6 +5,7 @@ use crate::filesystem::vfs::{
file::{File, FileMode}, file::{File, FileMode},
FilePrivateData, FileSystem, FileType, IndexNode, Metadata, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
}; };
use crate::libs::spinlock::SpinLockGuard;
use crate::mm::VirtAddr; use crate::mm::VirtAddr;
use crate::process::ProcessManager; use crate::process::ProcessManager;
use crate::syscall::user_access::copy_from_user; use crate::syscall::user_access::copy_from_user;
@ -94,12 +95,16 @@ impl IndexNode for LockedVmInode {
self self
} }
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
kdebug!("file private data:{:?}", _data); kdebug!("file private data:{:?}", _data);
return Ok(()); return Ok(());
} }
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(()); return Ok(());
} }
@ -190,7 +195,7 @@ impl IndexNode for LockedVmInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &mut [u8], _buf: &mut [u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }
@ -201,7 +206,7 @@ impl IndexNode for LockedVmInode {
_offset: usize, _offset: usize,
_len: usize, _len: usize,
_buf: &[u8], _buf: &[u8],
_data: &mut FilePrivateData, _data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
} }

View File

@ -0,0 +1,20 @@
ifeq ($(ARCH), x86_64)
CROSS_COMPILE=x86_64-linux-musl-
else ifeq ($(ARCH), riscv64)
CROSS_COMPILE=riscv64-linux-musl-
endif
CC=$(CROSS_COMPILE)gcc
all:
$(CC) -static -o test_pty test_pty.c
.PHONY: install clean
install: all
mv test_pty $(DADK_CURRENT_BUILD_DIR)/test_pty
clean:
rm test_pty *.o
fmt:

View File

@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <pty.h>
int main()
{
int ptm, pts;
char name[256];
struct termios term;
if (openpty(&ptm, &pts, name, NULL, NULL) == -1) {
perror("openpty");
exit(EXIT_FAILURE);
}
printf("slave name: %s fd: %d\n", name,pts);
tcgetattr(pts, &term);
term.c_lflag &= ~(ICANON | ECHO);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
tcsetattr(pts, TCSANOW, &term);
printf("before print to pty slave\n");
dprintf(pts, "Hello world!\n");
char buf[256];
ssize_t n = read(ptm, buf, sizeof(buf));
if (n > 0) {
printf("read %ld bytes from slave: %.*s", n, (int)n, buf);
}
dprintf(ptm, "hello world from master\n");
char nbuf[256];
ssize_t nn = read(pts, nbuf, sizeof(nbuf));
if (nn > 0) {
printf("read %ld bytes from master: %.*s", nn, (int)nn, nbuf);
}
close(ptm);
close(pts);
return 0;
}

View File

@ -0,0 +1,23 @@
{
"name": "test_pty",
"version": "0.1.0",
"description": "简单的pty测试程序",
"task_type": {
"BuildFromSource": {
"Local": {
"path": "apps/test_pty"
}
}
},
"depends": [],
"build": {
"build_command": "make install -j $(nproc)"
},
"install": {
"in_dragonos_path": "/bin"
},
"clean": {
"clean_command": "make clean"
},
"envs": []
}