实现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
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 {
Major(x)
}

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ use kdepends::thingbuf::StaticThingBuf;
use crate::{
arch::sched::sched,
driver::tty::virtual_terminal::virtual_console::CURRENT_VCNUM,
process::{
kthread::{KernelThreadClosure, KernelThreadMechanism},
ProcessControlBlock, ProcessFlags,
@ -54,7 +55,12 @@ fn tty_refresh_thread() -> i32 {
*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 kthread;
pub mod pty;
mod sysfs;
pub mod termios;
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::{
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 crate::{
@ -55,7 +60,7 @@ impl TtyCore {
ctrl: SpinLock::new(TtyContorlInfo::default()),
closing: AtomicBool::new(false),
flow: SpinLock::new(TtyFlowState::default()),
link: None,
link: RwLock::default(),
epitems: SpinLock::new(LinkedList::new()),
};
@ -138,7 +143,7 @@ impl TtyCore {
self.core()
.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> {
@ -252,7 +257,7 @@ pub struct TtyContorlInfo {
pub pgid: Option<Pid>,
/// packet模式下使用目前未用到
pub pktstatus: u8,
pub pktstatus: TtyPacketStatus,
pub packet: bool,
}
@ -296,7 +301,7 @@ pub struct TtyCoreData {
/// 流控状态
flow: SpinLock<TtyFlowState>,
/// 链接tty
link: Option<Arc<TtyCore>>,
link: RwLock<Weak<TtyCore>>,
/// epitems
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
}
@ -332,6 +337,11 @@ impl TtyCoreData {
*self.flags.read_irqsave()
}
#[inline]
pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
self.flags.write_irqsave()
}
#[inline]
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
self.termios.read_irqsave()
@ -348,6 +358,11 @@ impl TtyCoreData {
*termios_guard = termios;
}
#[inline]
pub fn count(&self) -> usize {
self.count.load(Ordering::SeqCst)
}
#[inline]
pub fn add_count(&self) {
self.count
@ -391,7 +406,36 @@ impl TtyCoreData {
#[inline]
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]
@ -463,6 +507,10 @@ impl TtyOperation for TtyCore {
.driver_funcs()
.set_termios(tty, old_termios);
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
self.core().tty_driver.driver_funcs().close(tty)
}
}
bitflags! {
@ -492,6 +540,19 @@ bitflags! {
/// 终端线路驱动程序已停止
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)]
@ -614,4 +675,12 @@ impl TtyIoctlCmd {
pub const TIOCCBRK: u32 = 0x5428;
/// Return the session ID of FD
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},
},
init::initcall::INITCALL_DEVICE,
libs::rwlock::RwLock,
libs::{
rwlock::{RwLock, RwLockWriteGuard},
spinlock::SpinLockGuard,
},
mm::VirtAddr,
net::event_poll::{EPollItem, EventPoll},
process::ProcessManager,
@ -38,10 +41,11 @@ use crate::{
use super::{
kthread::tty_flush_thread_init,
pty::unix98pty::ptmx_open,
sysfs::sys_class_tty_instance,
termios::WindowSize,
tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_job_control::TtyJobCtrlManager,
virtual_terminal::vty_init,
};
@ -72,13 +76,30 @@ impl InnerTtyDevice {
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)]
#[cast_to([sync] Device)]
pub struct TtyDevice {
name: &'static str,
name: String,
id_table: IdTable,
tty_type: TtyType,
inner: RwLock<InnerTtyDevice>,
kobj_state: LockedKObjectState,
/// TTY所属的文件系统
@ -86,7 +107,7 @@ pub struct 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 = TtyDevice {
name,
@ -94,23 +115,37 @@ impl TtyDevice {
inner: RwLock::new(InnerTtyDevice::new()),
kobj_state: LockedKObjectState::new(None),
fs: RwLock::new(Weak::default()),
tty_type,
};
dev.inner.write().metadata.raw_dev = dev_num;
Arc::new(dev)
}
pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
self.inner.write()
}
}
impl IndexNode for TtyDevice {
fn open(
&self,
data: &mut crate::filesystem::vfs::FilePrivateData,
mut data: SpinLockGuard<FilePrivateData>,
mode: &crate::filesystem::vfs::file::FileMode,
) -> 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 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
*data = FilePrivateData::Tty(TtyFilePrivateData {
@ -148,14 +183,16 @@ impl IndexNode for TtyDevice {
_offset: usize,
len: usize,
buf: &mut [u8],
data: &mut crate::filesystem::vfs::FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
let ld = tty.ldisc();
let mut offset = 0;
let mut cookie = false;
@ -188,15 +225,15 @@ impl IndexNode for TtyDevice {
_offset: usize,
len: usize,
buf: &[u8],
data: &mut crate::filesystem::vfs::FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
let mut count = len;
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
let ld = tty.ldisc();
let core = tty.core();
let mut chunk = 2048;
@ -239,7 +276,7 @@ impl IndexNode for TtyDevice {
}
fn as_any_ref(&self) -> &dyn core::any::Any {
todo!()
self
}
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())
}
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(())
}
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> {
Ok(())
}
fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
@ -485,8 +535,14 @@ impl CharDevice for TtyDevice {
#[derive(Debug, Clone)]
pub struct TtyFilePrivateData {
tty: Arc<TtyCore>,
mode: FileMode,
pub tty: Arc<TtyCore>,
pub mode: FileMode,
}
impl TtyFilePrivateData {
pub fn tty(&self) -> Arc<TtyCore> {
self.tty.clone()
}
}
/// 初始化tty设备和console子设备
@ -494,19 +550,21 @@ pub struct TtyFilePrivateData {
#[inline(never)]
pub fn tty_init() -> Result<(), SystemError> {
let tty = TtyDevice::new(
"tty0",
"tty0".to_string(),
IdTable::new(
String::from("tty0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
),
TtyType::Tty,
);
let console = TtyDevice::new(
"console",
"console".to_string(),
IdTable::new(
String::from("console"),
Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
),
TtyType::Tty,
);
// 注册tty设备
@ -536,8 +594,8 @@ pub fn tty_init() -> Result<(), SystemError> {
// 将这两个设备注册到devfsTODO这里console设备应该与tty在一个设备group里面
device_register(tty.clone())?;
device_register(console.clone())?;
devfs_register(tty.name, tty)?;
devfs_register(console.name, console)?;
devfs_register(&tty.name.clone(), tty)?;
devfs_register(&console.name.clone(), console)?;
serial_init()?;

View File

@ -1,8 +1,8 @@
use core::{fmt::Debug, sync::atomic::Ordering};
use core::fmt::Debug;
use alloc::{
string::{String, ToString},
sync::Arc,
sync::{Arc, Weak},
vec::Vec,
};
use hashbrown::HashMap;
@ -20,38 +20,46 @@ use crate::{
},
tty::tty_port::TtyPortState,
},
libs::spinlock::SpinLock,
libs::{
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
};
use super::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager,
tty_port::TTY_PORTS,
virtual_terminal::virtual_console::CURRENT_VCNUM,
tty_port::{DefaultTtyPort, TtyPort},
};
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;
impl TtyDriverManager {
pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
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);
if dev_num < base || dev_num.data() > base.data() + driver.device_count {
continue;
}
return Some((index, driver.clone()));
return Some(((dev_num.data() - base.data()) as usize, driver.clone()));
}
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 {
let dev_num = CharDevOps::alloc_chardev_region(
@ -69,11 +77,12 @@ impl TtyDriverManager {
driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
// 加入全局TtyDriver表
TTY_DRIVERS.lock().push(Arc::new(driver));
let driver = Arc::new(driver);
TTY_DRIVERS.lock().push(driver.clone());
// TODO: 加入procfs?
Ok(())
Ok(driver)
}
}
@ -104,11 +113,13 @@ pub struct TtyDriver {
/// 驱动程序标志
flags: TtyDriverFlag,
/// pty链接此driver的入口
pty: Option<Arc<TtyDriver>>,
other_pty_driver: RwLock<Weak<TtyDriver>>,
/// 具体类型的tty驱动方法
driver_funcs: Arc<dyn TtyOperation>,
/// 管理的tty设备列表
ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
/// 管理的端口列表
ports: RwLock<Vec<Arc<dyn TtyPort>>>,
// procfs入口?
}
@ -124,6 +135,10 @@ impl TtyDriver {
default_termios: Termios,
driver_funcs: Arc<dyn TtyOperation>,
) -> 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 {
driver_name: Default::default(),
name: node_name,
@ -135,10 +150,11 @@ impl TtyDriver {
tty_driver_sub_type: Default::default(),
init_termios: default_termios,
flags: TtyDriverFlag::empty(),
pty: Default::default(),
other_pty_driver: Default::default(),
driver_funcs,
ttys: SpinLock::new(HashMap::new()),
saved_termios: Vec::with_capacity(count as usize),
ports: RwLock::new(ports),
}
}
@ -162,34 +178,65 @@ impl TtyDriver {
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]
pub fn flags(&self) -> TtyDriverFlag {
self.flags
}
#[inline]
fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
let device_guard = self.ttys.lock();
return device_guard.get(&index).cloned();
fn lookup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
let ret = self
.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> {
let tty = tty_core.core();
let tty_index = tty.index();
// 初始化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);
}
}
tty.init_termios();
// TODO:设置termios波特率
tty.add_count();
self.ttys.lock().insert(tty_index, tty_core);
self.ttys.lock().insert(tty.index(), tty_core);
Ok(())
}
@ -210,7 +257,10 @@ impl TtyDriver {
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);
Self::driver_install_tty(driver.clone(), tty.clone())?;
@ -218,8 +268,9 @@ impl TtyDriver {
let core = tty.core();
if core.port().is_none() {
TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty));
tty.set_port(TTY_PORTS[core.index()].clone());
let ports = driver.ports.read();
ports[core.index()].setup_internal_tty(Arc::downgrade(&tty));
tty.set_port(ports[core.index()].clone());
}
TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
@ -228,11 +279,8 @@ impl TtyDriver {
}
/// ## 通过设备号找到对应驱动并且初始化Tty
pub fn open_tty(dev_num: DeviceNumber) -> Result<Arc<TtyCore>, SystemError> {
let (index, driver) =
TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
let tty = match driver.lockup_tty(index) {
pub fn open_tty(index: usize, driver: Arc<TtyDriver>) -> Result<Arc<TtyCore>, SystemError> {
let tty = match driver.lookup_tty(index) {
Some(tty) => {
// TODO: 暂时这么写因为还没写TtyPort
if tty.core().port().is_none() {
@ -247,8 +295,6 @@ impl TtyDriver {
None => Self::init_tty_device(driver, index)?,
};
CURRENT_VCNUM.store(index as isize, Ordering::SeqCst);
return Ok(tty);
}
@ -259,10 +305,6 @@ impl TtyDriver {
pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
self.tty_driver_sub_type
}
pub fn init_termios(&self) -> Termios {
self.init_termios
}
}
impl KObject for TtyDriver {
@ -368,7 +410,9 @@ pub trait TtyOperation: Sync + Send + Debug {
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> {
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> {
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)]

View File

@ -7,7 +7,7 @@ use crate::filesystem::vfs::file::FileMode;
use super::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData},
tty_core::{TtyCore, TtyCoreData, TtyFlag},
};
pub mod ntty;
@ -99,7 +99,7 @@ impl TtyLdiscManager {
/// ### 参数
/// - tty需要设置的tty
/// - 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 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(())
}

View File

@ -10,7 +10,7 @@ use crate::{
arch::ipc::signal::Signal,
driver::tty::{
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_job_control::TtyJobCtrlManager,
},
@ -812,6 +812,10 @@ impl NTtyData {
self.read_flags.set_all(false);
self.pushing = false;
self.lookahead_count = 0;
if tty.core().link().is_some() {
self.packet_mode_flush(tty.core());
}
}
}
@ -1521,6 +1525,17 @@ impl NTtyData {
}
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 {
@ -1551,7 +1566,10 @@ impl TtyLineDiscipline for NTtyLinediscipline {
ldata.lookahead_count = 0;
// todo: kick worker?
// todo: packet mode?
// packet mode?
if core.link().is_some() {
ldata.packet_mode_flush(core);
}
Ok(())
}
@ -1618,12 +1636,31 @@ impl TtyLineDiscipline for NTtyLinediscipline {
}
}
let packet = core.contorl_info_irqsave().packet;
let mut ret: Result<usize, SystemError> = Ok(0);
// 记录读取前 的tail
let tail = ldata.read_tail;
drop(ldata);
while nr != 0 {
// 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 core = tty.core();
@ -1676,7 +1713,11 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} else {
// 非标准模式
// 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)?
&& offset >= minimum
@ -2025,7 +2066,14 @@ impl TtyLineDiscipline for NTtyLinediscipline {
if core.contorl_info_irqsave().packet {
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(
EPollEventType::EPOLLPRI
| EPollEventType::EPOLLIN

View File

@ -1,36 +1,29 @@
use core::{fmt::Debug, sync::atomic::Ordering};
use alloc::{
sync::{Arc, Weak},
vec::Vec,
};
use alloc::sync::{Arc, Weak};
use kdepends::thingbuf::mpsc;
use system_error::SystemError;
use crate::{
driver::tty::virtual_terminal::MAX_NR_CONSOLES,
libs::spinlock::{SpinLock, SpinLockGuard},
use crate::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;
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
#[inline]
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)]
@ -41,6 +34,14 @@ pub struct TtyPortData {
sender: mpsc::Sender<u8>,
receiver: mpsc::Receiver<u8>,
tty: Weak<TtyCore>,
/// 内部tty即与port直接相连的
internal_tty: Weak<TtyCore>,
}
impl Default for TtyPortData {
fn default() -> Self {
Self::new()
}
}
impl TtyPortData {
@ -52,11 +53,12 @@ impl TtyPortData {
sender,
receiver,
tty: Weak::new(),
internal_tty: Weak::new(),
}
}
pub fn tty(&self) -> Option<Arc<TtyCore>> {
self.tty.upgrade()
pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
self.internal_tty.upgrade()
}
}
@ -80,13 +82,13 @@ pub trait TtyPort: Sync + Send + Debug {
}
/// 为port设置tty
fn setup_tty(&self, tty: Weak<TtyCore>) {
self.port_data().tty = tty;
fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
self.port_data().internal_tty = tty;
}
/// 作为客户端的tty ports接收数据
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();

View File

@ -1,6 +1,10 @@
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 crate::{
@ -21,7 +25,7 @@ use super::{
console::ConsoleSwitch,
termios::{InputMode, TTY_STD_TERMIOS},
tty_core::{TtyCore, TtyCoreData},
tty_device::TtyDevice,
tty_device::{TtyDevice, TtyType},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverType, TtyOperation},
};
@ -191,8 +195,12 @@ impl TtyOperation for TtyConsoleDriverInner {
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
CURRENT_VCNUM.store(tty_core.index() as isize, Ordering::SeqCst);
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
#[inline(never)]
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);
self.flush_chars(tty);
ret
@ -227,6 +238,10 @@ impl TtyOperation for TtyConsoleDriverInner {
// TODO
Err(SystemError::ENOIOCTLCMD)
}
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
Ok(())
}
}
#[derive(Debug, Clone)]
@ -264,11 +279,12 @@ pub struct DrawRegion {
pub fn vty_init() -> Result<(), SystemError> {
// 注册虚拟终端设备并将虚拟终端设备加入到文件系统
let vc0 = TtyDevice::new(
"vc0",
"vc0".to_string(),
IdTable::new(
String::from("vc0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
),
TtyType::Tty,
);
// 注册tty设备
// CharDevOps::cdev_add(

View File

@ -9,7 +9,11 @@ use bitmap::{traits::BitMapOps, StaticBitmap};
use crate::{
driver::{
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},
process::Pid,
@ -142,6 +146,9 @@ pub struct VirtualConsoleData {
/// 对应的Console Driver funcs
driver_funcs: Option<Weak<dyn ConsoleSwitch>>,
/// 对应端口
port: Arc<dyn TtyPort>,
}
impl VirtualConsoleData {
@ -204,9 +211,15 @@ impl VirtualConsoleData {
driver_funcs: None,
cursor_type: VcCursor::empty(),
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) {
if let Some(rows) = rows {
self.rows = rows;

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@ use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
};
use crate::libs::spinlock::SpinLockGuard;
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{
string::String,
@ -71,11 +72,15 @@ impl IndexNode for LockedZeroInode {
self
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(());
}
@ -109,7 +114,7 @@ impl IndexNode for LockedZeroInode {
_offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
if buf.len() < len {
return Err(SystemError::EINVAL);
@ -128,7 +133,7 @@ impl IndexNode for LockedZeroInode {
_offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
if buf.len() < len {
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,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
match &guard.inode_type {
@ -1397,7 +1397,7 @@ impl IndexNode for LockedFATInode {
offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
@ -1566,11 +1566,15 @@ impl IndexNode for LockedFATInode {
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(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(());
}

View File

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

View File

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

View File

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

View File

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

View File

@ -19,6 +19,7 @@ use crate::{
use super::{
file::FileMode,
mount::MountFSInode,
utils::{rsplit_path, user_path_at},
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"))
};
// 迁移挂载点
mountpoint
.mount(fs.inner_filesystem())
.unwrap_or_else(|_| panic!("Failed to migrate {mountpoint_name} "));
let inode = mountpoint.arc_any().downcast::<MountFSInode>().unwrap();
inode.do_mount(inode.inode_id(), fs.self_ref())?;
return Ok(());
}

View File

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

View File

@ -9,7 +9,10 @@ use alloc::{
};
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::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
@ -34,6 +37,7 @@ pub struct MountFS {
/// @brief MountFS的Index Node 注意这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
#[derive(Debug)]
#[cast_to([sync] IndexNode)]
pub struct MountFSInode {
/// 当前挂载点对应到具体的文件系统的Inode
inner_inode: Arc<dyn IndexNode>,
@ -88,6 +92,10 @@ impl MountFS {
pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
return self.inner_filesystem.clone();
}
pub fn self_ref(&self) -> Arc<Self> {
self.self_ref.upgrade().unwrap()
}
}
impl MountFSInode {
@ -132,14 +140,37 @@ impl MountFSInode {
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 {
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);
}
fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return self.inner_inode.close(data);
}
@ -169,7 +200,7 @@ impl IndexNode for MountFSInode {
offset: usize,
len: usize,
buf: &mut [u8],
data: &mut FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
return self.inner_inode.read_at(offset, len, buf, data);
}
@ -179,7 +210,7 @@ impl IndexNode for MountFSInode {
offset: usize,
len: usize,
buf: &[u8],
data: &mut FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
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()));
// 将新的挂载点-挂载文件系统添加到父级的挂载树
self.mount_fs
.mountpoints
.lock()
.insert(metadata.inode_id, new_mount_fs.clone());
self.do_mount(metadata.inode_id, new_mount_fs.clone())?;
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) {

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
use crate::{
driver::{
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,
},
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",
character as char
);
let port = TTY_PORTS[current_vcnum as usize].clone();
let tty = port.port_data().tty();
let port = tty_port(current_vcnum as usize);
let tty = port.port_data().internal_tty();
if let Some(tty) = tty {
send_to_default_serial8250_port(&[character]);
return tty

View File

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

View File

@ -278,11 +278,17 @@ pub struct EventWaitQueue {
wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
}
impl Default for EventWaitQueue {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)]
impl EventWaitQueue {
pub fn new() -> 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,
/// 对应的文件
file: Weak<SpinLock<File>>,
file: Weak<File>,
}
impl EPollItem {
@ -90,7 +90,7 @@ impl EPollItem {
epoll: Weak<SpinLock<EventPoll>>,
events: EPollEvent,
fd: i32,
file: Weak<SpinLock<File>>,
file: Weak<File>,
) -> Self {
Self {
epoll,
@ -108,7 +108,7 @@ impl EPollItem {
&self.event
}
pub fn file(&self) -> Weak<SpinLock<File>> {
pub fn file(&self) -> Weak<File> {
self.file.clone()
}
@ -122,7 +122,7 @@ impl EPollItem {
if file.is_none() {
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;
return EPollEventType::from_bits_truncate(events);
}
@ -154,7 +154,7 @@ impl IndexNode for EPollInode {
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: &mut crate::filesystem::vfs::FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
@ -164,7 +164,7 @@ impl IndexNode for EPollInode {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut crate::filesystem::vfs::FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
@ -190,7 +190,7 @@ impl IndexNode for EPollInode {
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();
@ -208,9 +208,7 @@ impl IndexNode for EPollInode {
.get_file_by_fd(fd);
if file.is_some() {
file.unwrap()
.lock_irqsave()
.remove_epoll(&Arc::downgrade(&self.epoll.0))?;
file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?;
}
epoll.ep_items.remove(&fd);
@ -219,7 +217,11 @@ impl IndexNode for EPollInode {
Ok(())
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(())
}
}
@ -250,7 +252,7 @@ impl EventPoll {
)?;
// 设置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 fd_table = current_pcb.fd_table();
@ -321,7 +323,7 @@ impl EventPoll {
}
// 从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 = {
if nonblock {
// 如果设置非阻塞,则尝试获取一次锁
@ -412,7 +414,7 @@ impl EventPoll {
// 从epoll文件获取到epoll
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())
}
if let Some(epoll_data) = epolldata {
@ -583,8 +585,8 @@ impl EventPoll {
}
// ### 查看文件是否为epoll文件
fn is_epoll_file(file: &Arc<SpinLock<File>>) -> bool {
if let FilePrivateData::EPoll(_) = file.lock_irqsave().private_data {
fn is_epoll_file(file: &Arc<File>) -> bool {
if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
return true;
}
return false;
@ -592,7 +594,7 @@ impl EventPoll {
fn ep_insert(
epoll_guard: &mut SpinLockGuard<EventPoll>,
dst_file: Arc<SpinLock<File>>,
dst_file: Arc<File>,
epitem: Arc<EPollItem>,
) -> Result<(), SystemError> {
if Self::is_epoll_file(&dst_file) {
@ -600,7 +602,7 @@ impl EventPoll {
// 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 {
// 如果目标文件不支持poll
return Err(SystemError::ENOSYS);
@ -624,19 +626,17 @@ impl EventPoll {
return Err(SystemError::ENOSYS);
}
dst_file.lock_irqsave().add_epoll(epitem.clone())?;
dst_file.add_epoll(epitem.clone())?;
Ok(())
}
pub fn ep_remove(
epoll: &mut SpinLockGuard<EventPoll>,
fd: i32,
dst_file: Option<Arc<SpinLock<File>>>,
dst_file: Option<Arc<File>>,
) -> Result<(), SystemError> {
if let Some(dst_file) = dst_file {
let mut file_guard = dst_file.lock_irqsave();
file_guard.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
}
let epitem = epoll.ep_items.remove(&fd).unwrap();

View File

@ -299,12 +299,16 @@ impl 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);
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);
if prev_ref_count == 1 {
// 最后一次关闭,需要释放
@ -333,7 +337,7 @@ impl IndexNode for SocketInode {
_offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
self.0.lock_no_preempt().read(&mut buf[0..len]).0
}
@ -343,7 +347,7 @@ impl IndexNode for SocketInode {
_offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
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 fd_table_guard = binding.read();
let binding = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
let file = binding.lock();
let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
if file.file_type() != FileType::Socket {
return Err(SystemError::ENOTSOCK);
}

View File

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

View File

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

View File

@ -5,6 +5,7 @@ use crate::filesystem::vfs::{
file::{File, FileMode},
FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
};
use crate::libs::spinlock::SpinLockGuard;
use crate::process::ProcessManager;
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
use crate::{filesystem, kdebug};
@ -88,12 +89,16 @@ impl IndexNode for LockedKvmInode {
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);
return Ok(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(());
}
@ -158,7 +163,7 @@ impl IndexNode for LockedKvmInode {
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}
@ -169,7 +174,7 @@ impl IndexNode for LockedKvmInode {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
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,
Metadata,
};
use crate::libs::spinlock::SpinLockGuard;
use crate::mm::VirtAddr;
use crate::syscall::user_access::copy_from_user;
use crate::virt::kvm::vcpu::Vcpu;
@ -96,12 +97,16 @@ impl IndexNode for LockedVcpuInode {
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);
return Ok(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(());
}
@ -197,7 +202,7 @@ impl IndexNode for LockedVcpuInode {
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}
@ -208,7 +213,7 @@ impl IndexNode for LockedVcpuInode {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}

View File

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