mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
完善Tty的RawMode (#577)
* 完善rowmode,改掉一部分bug * 增加两个ansi拓展功能功能,以及标记部分函数nerve inline * 修改do_signal和其他中断上下文锁未关中断,以及拓展tty功能,修改tty几个算法bug * 修改两个锁 * 修改syscall_64 * update
This commit is contained in:
parent
840045af94
commit
52bcb59e92
@ -327,6 +327,7 @@ ENTRY(ignore_int)
|
|||||||
|
|
||||||
ENTRY(syscall_64)
|
ENTRY(syscall_64)
|
||||||
// 切换用户栈和内核栈
|
// 切换用户栈和内核栈
|
||||||
|
cli
|
||||||
swapgs
|
swapgs
|
||||||
movq %rsp, %gs:0x8
|
movq %rsp, %gs:0x8
|
||||||
movq %gs:0x0, %rsp
|
movq %gs:0x0, %rsp
|
||||||
@ -372,10 +373,12 @@ ENTRY(syscall_64)
|
|||||||
|
|
||||||
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
||||||
|
|
||||||
|
sti
|
||||||
callq *%rdx //调用服务程序
|
callq *%rdx //调用服务程序
|
||||||
|
|
||||||
// 将原本要返回的栈帧的栈指针传入do_signal的第一个参数
|
// 将原本要返回的栈帧的栈指针传入do_signal的第一个参数
|
||||||
movq %rsp, %rdi
|
movq %rsp, %rdi
|
||||||
|
|
||||||
callq do_signal
|
callq do_signal
|
||||||
|
|
||||||
cli
|
cli
|
||||||
|
@ -415,7 +415,8 @@ pub struct X86_64SignalArch;
|
|||||||
impl SignalArch for X86_64SignalArch {
|
impl SignalArch for X86_64SignalArch {
|
||||||
unsafe fn do_signal(frame: &mut TrapFrame) {
|
unsafe fn do_signal(frame: &mut TrapFrame) {
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let siginfo = pcb.try_siginfo(5);
|
|
||||||
|
let siginfo = pcb.try_siginfo_irqsave(5);
|
||||||
|
|
||||||
if unlikely(siginfo.is_none()) {
|
if unlikely(siginfo.is_none()) {
|
||||||
return;
|
return;
|
||||||
@ -437,7 +438,7 @@ impl SignalArch for X86_64SignalArch {
|
|||||||
let sig_block: SigSet = siginfo_read_guard.sig_block().clone();
|
let sig_block: SigSet = siginfo_read_guard.sig_block().clone();
|
||||||
drop(siginfo_read_guard);
|
drop(siginfo_read_guard);
|
||||||
|
|
||||||
let sig_guard = pcb.try_sig_struct_irq(5);
|
let sig_guard = pcb.try_sig_struct_irqsave(5);
|
||||||
if unlikely(sig_guard.is_none()) {
|
if unlikely(sig_guard.is_none()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -140,12 +140,12 @@ bitflags! {
|
|||||||
/// termios输入特性
|
/// termios输入特性
|
||||||
pub struct InputMode: u32 {
|
pub struct InputMode: u32 {
|
||||||
/// 如果设置了该标志,表示启用软件流控制。
|
/// 如果设置了该标志,表示启用软件流控制。
|
||||||
const IXON = 0x0200;
|
const IXON = 0x0400;
|
||||||
/// 如果设置了该标志,表示启用输入流控制。
|
/// 如果设置了该标志,表示启用输入流控制。
|
||||||
const IXOFF = 0x0400;
|
const IXOFF = 0x1000;
|
||||||
/// Map Uppercase to Lowercase on Input 将大写转换为小写
|
/// Map Uppercase to Lowercase on Input 将大写转换为小写
|
||||||
/// 表示不区分大小写
|
/// 表示不区分大小写
|
||||||
const IUCLC = 0x1000;
|
const IUCLC = 0x0200;
|
||||||
/// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。
|
/// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。
|
||||||
const IMAXBEL = 0x2000;
|
const IMAXBEL = 0x2000;
|
||||||
/// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。
|
/// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。
|
||||||
@ -176,46 +176,44 @@ bitflags! {
|
|||||||
/// termios输出特性
|
/// termios输出特性
|
||||||
pub struct OutputMode: u32 {
|
pub struct OutputMode: u32 {
|
||||||
/// 在输出时将换行符替换\r\n
|
/// 在输出时将换行符替换\r\n
|
||||||
const ONLCR = 0x00002;
|
const ONLCR = 0x00004;
|
||||||
/// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母
|
/// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母
|
||||||
const OLCUC = 0x00004;
|
const OLCUC = 0x00002;
|
||||||
|
|
||||||
/// 与NL协同 配置换行符的处理方式
|
/// 与NL协同 配置换行符的处理方式
|
||||||
const NLDLY = 0x00300;
|
const NLDLY = 0x00100;
|
||||||
const NL0 = 0x00000; // 不延迟换行
|
const NL0 = 0x00000; // 不延迟换行
|
||||||
const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行)
|
const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行)
|
||||||
const NL2 = 0x00200; // NL2 和 NL3保留,暂未使用
|
|
||||||
const NL3 = 0x00300;
|
|
||||||
|
|
||||||
/// 配置水平制表符的处理方式
|
/// 配置水平制表符的处理方式
|
||||||
const TABDLY = 0x00c00;
|
const TABDLY = 0x01800;
|
||||||
const TAB0 = 0x00000; // 不延迟水平制表符
|
const TAB0 = 0x00000; // 不延迟水平制表符
|
||||||
const TAB1 = 0x00400; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置
|
const TAB1 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置
|
||||||
const TAB2 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置
|
const TAB2 = 0x01000; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置
|
||||||
const TAB3 = 0x00c00; // TAB3 和 XTABS(与 TAB3 等效)保留,暂未使用
|
const TAB3 = 0x01800; // TAB3 和 XTABS(与 TAB3 等效)保留,暂未使用
|
||||||
const XTABS = 0x00c00;
|
const XTABS = 0x01800;
|
||||||
|
|
||||||
/// 配置回车符的处理方式
|
/// 配置回车符的处理方式
|
||||||
const CRDLY = 0x03000;
|
const CRDLY = 0x00600;
|
||||||
const CR0 = 0x00000; // 不延迟回车
|
const CR0 = 0x00000; // 不延迟回车
|
||||||
const CR1 = 0x01000; // 延迟回车(输出回车后等待一段时间再输出换行)
|
const CR1 = 0x02000; // 延迟回车(输出回车后等待一段时间再输出换行)
|
||||||
const CR2 = 0x02000; // CR2 和 CR3保留,暂未使用
|
const CR2 = 0x04000; // CR2 和 CR3保留,暂未使用
|
||||||
const CR3 = 0x03000;
|
const CR3 = 0x06000;
|
||||||
|
|
||||||
/// 配置换页符(form feed)的处理方式
|
/// 配置换页符(form feed)的处理方式
|
||||||
const FFDLY = 0x04000;
|
const FFDLY = 0x08000;
|
||||||
const FF0 = 0x00000; // 不延迟换页
|
const FF0 = 0x00000; // 不延迟换页
|
||||||
const FF1 = 0x04000; // 延迟换页
|
const FF1 = 0x08000; // 延迟换页
|
||||||
|
|
||||||
/// 配置退格符(backspace)的处理方式
|
/// 配置退格符(backspace)的处理方式
|
||||||
const BSDLY = 0x08000;
|
const BSDLY = 0x02000;
|
||||||
const BS0 = 0x00000; // 不延迟退格
|
const BS0 = 0x00000; // 不延迟退格
|
||||||
const BS1 = 0x08000; // 延迟退格
|
const BS1 = 0x02000; // 延迟退格
|
||||||
|
|
||||||
/// 配置垂直制表符(vertical tab)的处理方式
|
/// 配置垂直制表符(vertical tab)的处理方式
|
||||||
const VTDLY = 0x10000;
|
const VTDLY = 0x04000;
|
||||||
const VT0 = 0x00000; // 不延迟垂直制表符
|
const VT0 = 0x00000; // 不延迟垂直制表符
|
||||||
const VT1 = 0x10000; // 延迟垂直制表符
|
const VT1 = 0x04000; // 延迟垂直制表符
|
||||||
|
|
||||||
/// 表示执行输出处理,即启用输出处理函数
|
/// 表示执行输出处理,即启用输出处理函数
|
||||||
const OPOST = 0x01;
|
const OPOST = 0x01;
|
||||||
@ -234,13 +232,14 @@ bitflags! {
|
|||||||
/// 配置终端设备的基本特性和控制参数
|
/// 配置终端设备的基本特性和控制参数
|
||||||
pub struct ControlMode: u32 {
|
pub struct ControlMode: u32 {
|
||||||
/// Baud Rate Mask 指定波特率的掩码
|
/// Baud Rate Mask 指定波特率的掩码
|
||||||
const CBAUD = 0x000000ff;
|
const CBAUD = 0x0000100f;
|
||||||
/// Extra Baud Bits 指定更高的波特率位
|
/// Extra Baud Bits 指定更高的波特率位
|
||||||
const CBAUDEX = 0x00000000;
|
const CBAUDEX = 0x00001000;
|
||||||
/// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER,则通过以下位来设置自定义的波特率值
|
/// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER,则通过以下位来设置自定义的波特率值
|
||||||
const BOTHER = 0x0000001f;
|
const BOTHER = 0x00001000;
|
||||||
|
|
||||||
const B0 = 0x00000000;
|
/* Common CBAUD rates */
|
||||||
|
const B0 = 0x00000000; /* hang up */
|
||||||
const B50 = 0x00000001;
|
const B50 = 0x00000001;
|
||||||
const B75 = 0x00000002;
|
const B75 = 0x00000002;
|
||||||
const B110 = 0x00000003;
|
const B110 = 0x00000003;
|
||||||
@ -257,43 +256,43 @@ bitflags! {
|
|||||||
const B19200 = 0x0000000e;
|
const B19200 = 0x0000000e;
|
||||||
const B38400 = 0x0000000f;
|
const B38400 = 0x0000000f;
|
||||||
|
|
||||||
const B57600 = 0x00000010;
|
const B57600 = 0x00001001;
|
||||||
const B115200 = 0x00000011;
|
const B115200 = 0x00001002;
|
||||||
const B230400 = 0x00000012;
|
const B230400 = 0x00001003;
|
||||||
const B460800 = 0x00000013;
|
const B460800 = 0x00001004;
|
||||||
const B500000 = 0x00000014;
|
const B500000 = 0x00001005;
|
||||||
const B576000 = 0x00000015;
|
const B576000 = 0x00001006;
|
||||||
const B921600 = 0x00000016;
|
const B921600 = 0x00001007;
|
||||||
const B1000000 = 0x00000017;
|
const B1000000 = 0x00001008;
|
||||||
const B1152000 = 0x00000018;
|
const B1152000 = 0x00001009;
|
||||||
const B1500000 = 0x00000019;
|
const B1500000 = 0x0000100a;
|
||||||
const B2000000 = 0x0000001a;
|
const B2000000 = 0x0000100b;
|
||||||
const B2500000 = 0x0000001b;
|
const B2500000 = 0x0000100c;
|
||||||
const B3000000 = 0x0000001c;
|
const B3000000 = 0x0000100d;
|
||||||
const B3500000 = 0x0000001d;
|
const B3500000 = 0x0000100e;
|
||||||
const B4000000 = 0x0000001e;
|
const B4000000 = 0x0000100f;
|
||||||
|
|
||||||
/// 指定字符大小的掩码 以下位为特定字符大小
|
/// 指定字符大小的掩码 以下位为特定字符大小
|
||||||
const CSIZE = 0x00000300;
|
const CSIZE = 0x00000030;
|
||||||
const CS5 = 0x00000000;
|
const CS5 = 0x00000000;
|
||||||
const CS6 = 0x00000100;
|
const CS6 = 0x00000010;
|
||||||
const CS7 = 0x00000200;
|
const CS7 = 0x00000020;
|
||||||
const CS8 = 0x00000300;
|
const CS8 = 0x00000030;
|
||||||
|
|
||||||
/// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位
|
/// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位
|
||||||
const CSTOPB = 0x00000400;
|
const CSTOPB = 0x00000040;
|
||||||
/// 表示启用接收器。如果未设置,则禁用接收器。
|
/// 表示启用接收器。如果未设置,则禁用接收器。
|
||||||
const CREAD = 0x00000800;
|
const CREAD = 0x00000080;
|
||||||
/// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。
|
/// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。
|
||||||
const PARENB = 0x00001000;
|
const PARENB = 0x00000100;
|
||||||
/// 表示启用奇校验。如果未设置,则表示启用偶校验。
|
/// 表示启用奇校验。如果未设置,则表示启用偶校验。
|
||||||
const PARODD = 0x00002000;
|
const PARODD = 0x00000200;
|
||||||
/// 表示在终端设备被关闭时挂断线路(执行挂断操作)
|
/// 表示在终端设备被关闭时挂断线路(执行挂断操作)
|
||||||
const HUPCL = 0x00004000;
|
const HUPCL = 0x00000400;
|
||||||
/// 表示忽略调制解调器的状态(DCD、DSR、CTS 等)
|
/// 表示忽略调制解调器的状态(DCD、DSR、CTS 等)
|
||||||
const CLOCAL = 0x00008000;
|
const CLOCAL = 0x00000800;
|
||||||
/// 指定输入波特率的掩码
|
/// 指定输入波特率的掩码
|
||||||
const CIBAUD = 0x00ff0000;
|
const CIBAUD = 0x100f0000;
|
||||||
|
|
||||||
const ADDRB = 0x20000000;
|
const ADDRB = 0x20000000;
|
||||||
}
|
}
|
||||||
@ -301,37 +300,37 @@ bitflags! {
|
|||||||
/// 配置终端设备的本地模式(local mode)或控制输入处理的行为
|
/// 配置终端设备的本地模式(local mode)或控制输入处理的行为
|
||||||
pub struct LocalMode: u32 {
|
pub struct LocalMode: u32 {
|
||||||
/// 启用中断字符(Ctrl-C、Ctrl-Z)
|
/// 启用中断字符(Ctrl-C、Ctrl-Z)
|
||||||
const ISIG = 0x00000080;
|
const ISIG = 0x00001;
|
||||||
/// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。
|
/// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。
|
||||||
const ICANON = 0x00000100;
|
const ICANON = 0x00002;
|
||||||
/// 表示启用大写模式,即输入输出都将被转换为大写。
|
/// 表示启用大写模式,即输入输出都将被转换为大写。
|
||||||
const XCASE = 0x00004000;
|
const XCASE = 0x00004;
|
||||||
/// 表示启用回显(显示用户输入的字符)
|
/// 表示启用回显(显示用户输入的字符)
|
||||||
const ECHO = 0x00000008;
|
const ECHO = 0x00008;
|
||||||
/// 表示在回显时将擦除的字符用 backspace 和空格字符显示。
|
/// 表示在回显时将擦除的字符用 backspace 和空格字符显示。
|
||||||
const ECHOE = 0x00000002;
|
const ECHOE = 0x00010;
|
||||||
/// 表示在回显时将换行符后的字符用空格字符显示。
|
/// 表示在回显时将换行符后的字符用空格字符显示。
|
||||||
const ECHOK = 0x00000004;
|
const ECHOK = 0x00020;
|
||||||
/// 表示在回显时将换行符显示为换行和回车符。
|
/// 表示在回显时将换行符显示为换行和回车符。
|
||||||
const ECHONL = 0x00000010;
|
const ECHONL = 0x00040;
|
||||||
/// 表示在收到中断(Ctrl-C)和退出(Ctrl-\)字符后,不清空输入和输出缓冲区。
|
/// 表示在收到中断(Ctrl-C)和退出(Ctrl-\)字符后,不清空输入和输出缓冲区。
|
||||||
const NOFLSH = 0x80000000;
|
const NOFLSH = 0x00080;
|
||||||
/// 表示在后台进程尝试写入终端时,发送停止信号(Ctrl-S)
|
/// 表示在后台进程尝试写入终端时,发送停止信号(Ctrl-S)
|
||||||
const TOSTOP = 0x00400000;
|
const TOSTOP = 0x00100;
|
||||||
/// 表示在回显时,显示控制字符为 ^ 加字符。
|
/// 表示在回显时,显示控制字符为 ^ 加字符。
|
||||||
const ECHOCTL= 0x00000040;
|
const ECHOCTL= 0x00200;
|
||||||
/// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。
|
/// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。
|
||||||
const ECHOPRT= 0x00000020;
|
const ECHOPRT= 0x00400;
|
||||||
/// 表示在回显时将 KILL 字符(Ctrl-U)用空格字符显示。
|
/// 表示在回显时将 KILL 字符(Ctrl-U)用空格字符显示。
|
||||||
const ECHOKE = 0x00000001;
|
const ECHOKE = 0x00800;
|
||||||
/// 表示输出正在被冲刷(flush),通常是由于输入/输出流的状态变化。
|
/// 表示输出正在被冲刷(flush),通常是由于输入/输出流的状态变化。
|
||||||
const FLUSHO = 0x00800000;
|
const FLUSHO = 0x01000;
|
||||||
/// 表示在规范模式下,存在需要重新打印的字符。
|
/// 表示在规范模式下,存在需要重新打印的字符。
|
||||||
const PENDIN = 0x20000000;
|
const PENDIN = 0x04000;
|
||||||
/// 表示启用实现定义的输入处理。
|
/// 表示启用实现定义的输入处理。
|
||||||
const IEXTEN = 0x00000400;
|
const IEXTEN = 0x08000;
|
||||||
/// 表示启用扩展的处理函数
|
/// 表示启用扩展的处理函数
|
||||||
const EXTPROC= 0x10000000;
|
const EXTPROC= 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TtySetTermiosOpt: u8 {
|
pub struct TtySetTermiosOpt: u8 {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::{fmt::Debug, sync::atomic::AtomicBool};
|
use core::{fmt::Debug, sync::atomic::AtomicBool};
|
||||||
|
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{collections::LinkedList, string::String, sync::Arc, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -11,7 +11,7 @@ use crate::{
|
|||||||
wait_queue::EventWaitQueue,
|
wait_queue::EventWaitQueue,
|
||||||
},
|
},
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
net::event_poll::EPollEventType,
|
net::event_poll::{EPollEventType, EPollItem},
|
||||||
process::Pid,
|
process::Pid,
|
||||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||||
};
|
};
|
||||||
@ -53,6 +53,7 @@ impl TtyCore {
|
|||||||
closing: AtomicBool::new(false),
|
closing: AtomicBool::new(false),
|
||||||
flow: SpinLock::new(TtyFlowState::default()),
|
flow: SpinLock::new(TtyFlowState::default()),
|
||||||
link: None,
|
link: None,
|
||||||
|
epitems: SpinLock::new(LinkedList::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return Arc::new(Self {
|
return Arc::new(Self {
|
||||||
@ -159,6 +160,13 @@ impl TtyCore {
|
|||||||
user_writer.copy_one_to_user(&termios, 0)?;
|
user_writer.copy_one_to_user(&termios, 0)?;
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
TtyIoctlCmd::TCSETS => {
|
||||||
|
return TtyCore::core_set_termios(
|
||||||
|
real_tty,
|
||||||
|
VirtAddr::new(arg),
|
||||||
|
TtySetTermiosOpt::TERMIOS_OLD,
|
||||||
|
);
|
||||||
|
}
|
||||||
TtyIoctlCmd::TCSETSW => {
|
TtyIoctlCmd::TCSETSW => {
|
||||||
return TtyCore::core_set_termios(
|
return TtyCore::core_set_termios(
|
||||||
real_tty,
|
real_tty,
|
||||||
@ -213,9 +221,7 @@ impl TtyCore {
|
|||||||
let mut termios = tty.core().termios_write();
|
let mut termios = tty.core().termios_write();
|
||||||
|
|
||||||
let old_termios = termios.clone();
|
let old_termios = termios.clone();
|
||||||
|
|
||||||
*termios = new_termios;
|
*termios = new_termios;
|
||||||
|
|
||||||
let tmp = termios.control_mode;
|
let tmp = termios.control_mode;
|
||||||
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
|
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
|
||||||
|
|
||||||
@ -300,6 +306,8 @@ pub struct TtyCoreData {
|
|||||||
flow: SpinLock<TtyFlowState>,
|
flow: SpinLock<TtyFlowState>,
|
||||||
/// 链接tty
|
/// 链接tty
|
||||||
link: Option<Arc<TtyCore>>,
|
link: Option<Arc<TtyCore>>,
|
||||||
|
/// epitems
|
||||||
|
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TtyCoreData {
|
impl TtyCoreData {
|
||||||
@ -335,17 +343,17 @@ impl TtyCoreData {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
|
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
|
||||||
self.termios.read()
|
self.termios.read_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
|
pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
|
||||||
self.termios.write()
|
self.termios.write_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_termios(&self, termios: Termios) {
|
pub fn set_termios(&self, termios: Termios) {
|
||||||
let mut termios_guard = self.termios.write();
|
let mut termios_guard = self.termios.write_irqsave();
|
||||||
*termios_guard = termios;
|
*termios_guard = termios;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,6 +402,11 @@ impl TtyCoreData {
|
|||||||
pub fn link(&self) -> Option<Arc<TtyCore>> {
|
pub fn link(&self) -> Option<Arc<TtyCore>> {
|
||||||
self.link.clone()
|
self.link.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn add_epitem(&self, epitem: Arc<EPollItem>) {
|
||||||
|
self.epitems.lock().push_back(epitem)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TTY 核心接口,不同的tty需要各自实现这个trait
|
/// TTY 核心接口,不同的tty需要各自实现这个trait
|
||||||
|
@ -30,8 +30,9 @@ use crate::{
|
|||||||
init::initcall::INITCALL_DEVICE,
|
init::initcall::INITCALL_DEVICE,
|
||||||
libs::rwlock::RwLock,
|
libs::rwlock::RwLock,
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
|
net::event_poll::{EPollItem, EventPoll},
|
||||||
process::ProcessManager,
|
process::ProcessManager,
|
||||||
syscall::user_access::UserBufferWriter,
|
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -131,7 +132,7 @@ impl IndexNode for TtyDevice {
|
|||||||
&& driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
|
&& driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
|
||||||
{
|
{
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let pcb_tty = pcb.sig_info().tty();
|
let pcb_tty = pcb.sig_info_irqsave().tty();
|
||||||
if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
|
if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
|
||||||
TtyJobCtrlManager::proc_set_tty(tty);
|
TtyJobCtrlManager::proc_set_tty(tty);
|
||||||
}
|
}
|
||||||
@ -210,7 +211,7 @@ impl IndexNode for TtyDevice {
|
|||||||
|
|
||||||
// 将数据从buf拷贝到writebuf
|
// 将数据从buf拷贝到writebuf
|
||||||
|
|
||||||
let ret = ld.write(tty.clone(), buf, size, mode)?;
|
let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
|
||||||
|
|
||||||
written += ret;
|
written += ret;
|
||||||
count -= ret;
|
count -= ret;
|
||||||
@ -219,7 +220,7 @@ impl IndexNode for TtyDevice {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if pcb.sig_info().sig_pending().has_pending() {
|
if pcb.sig_info_irqsave().sig_pending().has_pending() {
|
||||||
return Err(SystemError::ERESTARTSYS);
|
return Err(SystemError::ERESTARTSYS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,6 +274,20 @@ impl IndexNode for TtyDevice {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EventPoll::ADD_EPOLLITEM => {
|
||||||
|
let _ = UserBufferReader::new(
|
||||||
|
arg as *const Arc<EPollItem>,
|
||||||
|
core::mem::size_of::<Arc<EPollItem>>(),
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
let epitem = unsafe { &*(arg as *const Arc<EPollItem>) };
|
||||||
|
|
||||||
|
let core = tty.core();
|
||||||
|
|
||||||
|
core.add_epitem(epitem.clone());
|
||||||
|
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +334,16 @@ impl IndexNode for TtyDevice {
|
|||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
|
||||||
|
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
|
||||||
|
(tty_priv.tty.clone(), tty_priv.mode)
|
||||||
|
} else {
|
||||||
|
return Err(SystemError::EIO);
|
||||||
|
};
|
||||||
|
|
||||||
|
tty.ldisc().poll(tty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceINode for TtyDevice {
|
impl DeviceINode for TtyDevice {
|
||||||
|
@ -34,7 +34,9 @@ impl TtyJobCtrlManager {
|
|||||||
pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> {
|
pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> {
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
|
|
||||||
if pcb.sig_info().tty().is_none() || !Arc::ptr_eq(&pcb.sig_info().tty().unwrap(), &tty) {
|
if pcb.sig_info_irqsave().tty().is_none()
|
||||||
|
|| !Arc::ptr_eq(&pcb.sig_info_irqsave().tty().unwrap(), &tty)
|
||||||
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +93,8 @@ impl TtyJobCtrlManager {
|
|||||||
|
|
||||||
let mut ctrl = tty.core().contorl_info_irqsave();
|
let mut ctrl = tty.core().contorl_info_irqsave();
|
||||||
|
|
||||||
if current.sig_info().tty().is_none()
|
if current.sig_info_irqsave().tty().is_none()
|
||||||
|| !Arc::ptr_eq(¤t.sig_info().tty().clone().unwrap(), &tty)
|
|| !Arc::ptr_eq(¤t.sig_info_irqsave().tty().clone().unwrap(), &tty)
|
||||||
|| ctrl.session.is_none()
|
|| ctrl.session.is_none()
|
||||||
|| ctrl.session.unwrap() != current.pid()
|
|| ctrl.session.unwrap() != current.pid()
|
||||||
{
|
{
|
||||||
@ -106,8 +108,8 @@ impl TtyJobCtrlManager {
|
|||||||
|
|
||||||
TtyIoctlCmd::TIOCGPGRP => {
|
TtyIoctlCmd::TIOCGPGRP => {
|
||||||
let current = ProcessManager::current_pcb();
|
let current = ProcessManager::current_pcb();
|
||||||
if current.sig_info().tty().is_some()
|
if current.sig_info_irqsave().tty().is_some()
|
||||||
&& !Arc::ptr_eq(¤t.sig_info().tty().unwrap(), &tty)
|
&& !Arc::ptr_eq(¤t.sig_info_irqsave().tty().unwrap(), &tty)
|
||||||
{
|
{
|
||||||
return Err(SystemError::ENOTTY);
|
return Err(SystemError::ENOTTY);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ pub trait TtyLineDiscipline: Sync + Send + Debug {
|
|||||||
/// - old: 之前的termios,如果为None则表示第一次设置
|
/// - old: 之前的termios,如果为None则表示第一次设置
|
||||||
fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>;
|
fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>;
|
||||||
|
|
||||||
fn poll(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
|
fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, SystemError>;
|
||||||
fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
|
fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
|
||||||
|
|
||||||
/// ## 接收数据
|
/// ## 接收数据
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use core::intrinsics::likely;
|
||||||
use core::ops::BitXor;
|
use core::ops::BitXor;
|
||||||
|
|
||||||
use bitmap::{traits::BitMapOps, StaticBitmap};
|
use bitmap::{traits::BitMapOps, StaticBitmap};
|
||||||
@ -249,11 +250,10 @@ impl NTtyData {
|
|||||||
|| termios.local_mode.contains(LocalMode::IEXTEN);
|
|| termios.local_mode.contains(LocalMode::IEXTEN);
|
||||||
|
|
||||||
let look_ahead = self.lookahead_count.min(count);
|
let look_ahead = self.lookahead_count.min(count);
|
||||||
|
|
||||||
if self.real_raw {
|
if self.real_raw {
|
||||||
todo!("tty real raw mode todo");
|
self.receive_buf_real_raw(buf, count);
|
||||||
} else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) {
|
} else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) {
|
||||||
todo!("tty raw mode todo");
|
self.receive_buf_raw(buf, flags, count);
|
||||||
} else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) {
|
} else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) {
|
||||||
todo!()
|
todo!()
|
||||||
} else {
|
} else {
|
||||||
@ -282,7 +282,47 @@ impl NTtyData {
|
|||||||
if self.read_cnt() > 0 {
|
if self.read_cnt() > 0 {
|
||||||
tty.core()
|
tty.core()
|
||||||
.read_wq()
|
.read_wq()
|
||||||
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64);
|
.wakeup_any((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive_buf_real_raw(&mut self, buf: &[u8], mut count: usize) {
|
||||||
|
let mut head = ntty_buf_mask(self.read_head);
|
||||||
|
let mut n = count.min(NTTY_BUFSIZE - head);
|
||||||
|
|
||||||
|
// 假如有一部分在队列头部,则这部分是拷贝尾部部分
|
||||||
|
self.read_buf[head..(head + n)].copy_from_slice(&buf[0..n]);
|
||||||
|
self.read_head += n;
|
||||||
|
count -= n;
|
||||||
|
let offset = n;
|
||||||
|
|
||||||
|
// 假如有一部分在队列头部,则这部分是拷贝头部部分
|
||||||
|
head = ntty_buf_mask(self.read_head);
|
||||||
|
n = count.min(NTTY_BUFSIZE - head);
|
||||||
|
self.read_buf[head..(head + n)].copy_from_slice(&buf[offset..(offset + n)]);
|
||||||
|
self.read_head += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive_buf_raw(&mut self, buf: &[u8], flags: Option<&[u8]>, mut count: usize) {
|
||||||
|
// TTY_NORMAL 目前这部分未做,所以先占位置而不做抽象
|
||||||
|
let mut flag = 1;
|
||||||
|
let mut f_offset = 0;
|
||||||
|
let mut c_offset = 0;
|
||||||
|
while count != 0 {
|
||||||
|
if flags.is_some() {
|
||||||
|
flag = flags.as_ref().unwrap()[f_offset];
|
||||||
|
f_offset += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if likely(flag == 1) {
|
||||||
|
self.read_buf[self.read_head] = buf[c_offset];
|
||||||
|
c_offset += 1;
|
||||||
|
self.read_head += 1;
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
count -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +404,7 @@ impl NTtyData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) {
|
pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) {
|
||||||
let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done);
|
let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done);
|
||||||
let termios = tty.core().termios();
|
let termios = tty.core().termios();
|
||||||
@ -467,9 +508,9 @@ impl NTtyData {
|
|||||||
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
||||||
self.read_head += 1;
|
self.read_head += 1;
|
||||||
self.canon_head = self.read_head;
|
self.canon_head = self.read_head;
|
||||||
tty.core()
|
tty.core().read_wq().wakeup_any(
|
||||||
.read_wq()
|
(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
|
||||||
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,9 +521,9 @@ impl NTtyData {
|
|||||||
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
||||||
self.read_head += 1;
|
self.read_head += 1;
|
||||||
self.canon_head = self.read_head;
|
self.canon_head = self.read_head;
|
||||||
tty.core()
|
tty.core().read_wq().wakeup_any(
|
||||||
.read_wq()
|
(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
|
||||||
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,9 +549,9 @@ impl NTtyData {
|
|||||||
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
self.read_buf[ntty_buf_mask(self.read_head)] = c;
|
||||||
self.read_head += 1;
|
self.read_head += 1;
|
||||||
self.canon_head = self.read_head;
|
self.canon_head = self.read_head;
|
||||||
tty.core()
|
tty.core().read_wq().wakeup_any(
|
||||||
.read_wq()
|
(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
|
||||||
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -540,6 +581,7 @@ impl NTtyData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ## ntty默认eraser function
|
/// ## ntty默认eraser function
|
||||||
|
#[inline(never)]
|
||||||
fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) {
|
fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) {
|
||||||
if self.read_head == self.canon_head {
|
if self.read_head == self.canon_head {
|
||||||
return;
|
return;
|
||||||
@ -907,7 +949,7 @@ impl NTtyData {
|
|||||||
// 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
|
// 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
|
||||||
// TODO: tty审计?
|
// TODO: tty审计?
|
||||||
to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
|
to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
|
||||||
to[size..].copy_from_slice(&self.read_buf[(tail + size)..(*n + tail)]);
|
to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]);
|
||||||
} else {
|
} else {
|
||||||
to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
|
to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
|
||||||
}
|
}
|
||||||
@ -975,7 +1017,7 @@ impl NTtyData {
|
|||||||
let size = if tail + n > NTTY_BUFSIZE {
|
let size = if tail + n > NTTY_BUFSIZE {
|
||||||
NTTY_BUFSIZE
|
NTTY_BUFSIZE
|
||||||
} else {
|
} else {
|
||||||
tail + *nr
|
tail + n
|
||||||
};
|
};
|
||||||
|
|
||||||
// 找到eol的坐标
|
// 找到eol的坐标
|
||||||
@ -1088,7 +1130,7 @@ impl NTtyData {
|
|||||||
let tail = self.read_tail & (NTTY_BUFSIZE - 1);
|
let tail = self.read_tail & (NTTY_BUFSIZE - 1);
|
||||||
|
|
||||||
// 计算出可读的字符数
|
// 计算出可读的字符数
|
||||||
let mut n = (NTTY_BUFSIZE - tail).min(self.read_tail);
|
let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail);
|
||||||
n = n.min(*nr);
|
n = n.min(*nr);
|
||||||
|
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
@ -1209,6 +1251,7 @@ impl NTtyData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
|
pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
|
||||||
let mut space = tty.write_room(tty.core());
|
let mut space = tty.write_room(tty.core());
|
||||||
let ospace = space;
|
let ospace = space;
|
||||||
@ -1519,6 +1562,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn read(
|
fn read(
|
||||||
&self,
|
&self,
|
||||||
tty: Arc<TtyCore>,
|
tty: Arc<TtyCore>,
|
||||||
@ -1555,7 +1599,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
return Ok(len - nr);
|
return Ok(len - nr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
|
if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
|
||||||
return Ok(len - nr);
|
return Ok(len - nr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1610,7 +1654,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ProcessManager::current_pcb()
|
if ProcessManager::current_pcb()
|
||||||
.sig_info()
|
.sig_info_irqsave()
|
||||||
.sig_pending()
|
.sig_pending()
|
||||||
.has_pending()
|
.has_pending()
|
||||||
{
|
{
|
||||||
@ -1666,6 +1710,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn write(
|
fn write(
|
||||||
&self,
|
&self,
|
||||||
tty: Arc<TtyCore>,
|
tty: Arc<TtyCore>,
|
||||||
@ -1687,7 +1732,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
// drop(ldata);
|
// drop(ldata);
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
loop {
|
loop {
|
||||||
if pcb.sig_info().sig_pending().has_pending() {
|
if pcb.sig_info_irqsave().sig_pending().has_pending() {
|
||||||
return Err(SystemError::ERESTARTSYS);
|
return Err(SystemError::ERESTARTSYS);
|
||||||
}
|
}
|
||||||
if core.flags().contains(TtyFlag::HUPPED) {
|
if core.flags().contains(TtyFlag::HUPPED) {
|
||||||
@ -1818,6 +1863,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn set_termios(
|
fn set_termios(
|
||||||
&self,
|
&self,
|
||||||
tty: Arc<TtyCore>,
|
tty: Arc<TtyCore>,
|
||||||
@ -1829,14 +1875,13 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
let contorl_chars = termios.control_characters;
|
let contorl_chars = termios.control_characters;
|
||||||
|
|
||||||
// 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
|
// 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
|
||||||
if old.is_none()
|
let mut spec_mode_changed = false;
|
||||||
|| (old.is_some()
|
if old.is_some() {
|
||||||
&& old
|
let local_mode = old.clone().unwrap().local_mode.bitxor(termios.local_mode);
|
||||||
.unwrap()
|
spec_mode_changed =
|
||||||
.local_mode
|
local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC);
|
||||||
.bitxor(termios.local_mode)
|
}
|
||||||
.contains(LocalMode::ICANON | LocalMode::EXTPROC))
|
if old.is_none() || spec_mode_changed {
|
||||||
{
|
|
||||||
// 重置read_flags
|
// 重置read_flags
|
||||||
ldata.read_flags.set_all(false);
|
ldata.read_flags.set_all(false);
|
||||||
|
|
||||||
@ -1859,10 +1904,8 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
ldata.lnext = false;
|
ldata.lnext = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置规范模式
|
// 设置模式
|
||||||
if termios.local_mode.contains(LocalMode::ICANON) {
|
ldata.icanon = termios.local_mode.contains(LocalMode::ICANON);
|
||||||
ldata.icanon = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置回显
|
// 设置回显
|
||||||
if termios.local_mode.contains(LocalMode::ECHO) {
|
if termios.local_mode.contains(LocalMode::ECHO) {
|
||||||
@ -1984,8 +2027,37 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
|
fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError> {
|
||||||
todo!()
|
let core = tty.core();
|
||||||
|
let ldata = self.disc_data();
|
||||||
|
|
||||||
|
let mut event = EPollEventType::empty();
|
||||||
|
if ldata.input_available(core.termios(), true) {
|
||||||
|
event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM)
|
||||||
|
}
|
||||||
|
|
||||||
|
if core.contorl_info_irqsave().packet {
|
||||||
|
let link = core.link();
|
||||||
|
if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 {
|
||||||
|
event.insert(
|
||||||
|
EPollEventType::EPOLLPRI
|
||||||
|
| EPollEventType::EPOLLIN
|
||||||
|
| EPollEventType::EPOLLRDNORM,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if core.flags().contains(TtyFlag::OTHER_CLOSED) {
|
||||||
|
event.insert(EPollEventType::EPOLLHUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if core.driver().driver_funcs().chars_in_buffer() < 256
|
||||||
|
&& core.driver().driver_funcs().write_room(core) > 0
|
||||||
|
{
|
||||||
|
event.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(event.bits() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
|
fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
|
||||||
|
@ -102,62 +102,8 @@ impl TtyConsoleDriverInner {
|
|||||||
console: Arc::new(BlittingFbConsole::new()?),
|
console: Arc::new(BlittingFbConsole::new()?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl TtyOperation for TtyConsoleDriverInner {
|
fn do_write(&self, tty: &TtyCoreData, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
|
||||||
fn install(&self, _driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
|
|
||||||
let tty_core = tty.core();
|
|
||||||
let mut vc_data = VIRT_CONSOLES[tty_core.index()].lock();
|
|
||||||
|
|
||||||
self.console.con_init(&mut vc_data, true)?;
|
|
||||||
if vc_data.complement_mask == 0 {
|
|
||||||
vc_data.complement_mask = if vc_data.color_mode { 0x7700 } else { 0x0800 };
|
|
||||||
}
|
|
||||||
vc_data.s_complement_mask = vc_data.complement_mask;
|
|
||||||
// vc_data.bytes_per_row = vc_data.cols << 1;
|
|
||||||
vc_data.index = tty_core.index();
|
|
||||||
vc_data.bottom = vc_data.rows;
|
|
||||||
vc_data.set_driver_funcs(Arc::downgrade(
|
|
||||||
&(self.console.clone() as Arc<dyn ConsoleSwitch>),
|
|
||||||
));
|
|
||||||
|
|
||||||
// todo: unicode字符集处理?
|
|
||||||
|
|
||||||
if vc_data.cols > VC_MAXCOL || vc_data.rows > VC_MAXROW {
|
|
||||||
return Err(SystemError::EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
vc_data.init(None, None, true);
|
|
||||||
vc_data.update_attr();
|
|
||||||
|
|
||||||
let window_size = tty_core.window_size_upgradeable();
|
|
||||||
if window_size.col == 0 && window_size.row == 0 {
|
|
||||||
let mut window_size = window_size.upgrade();
|
|
||||||
window_size.col = vc_data.cols as u16;
|
|
||||||
window_size.row = vc_data.rows as u16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if vc_data.utf {
|
|
||||||
tty_core.termios_write().input_mode.insert(InputMode::IUTF8);
|
|
||||||
} else {
|
|
||||||
tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加入sysfs?
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_room(&self, _tty: &TtyCoreData) -> usize {
|
|
||||||
32768
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
|
|
||||||
fn write(&self, tty: &TtyCoreData, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
|
|
||||||
// 关闭中断
|
// 关闭中断
|
||||||
let mut vc_data = tty.vc_data_irqsave();
|
let mut vc_data = tty.vc_data_irqsave();
|
||||||
|
|
||||||
@ -204,7 +150,70 @@ impl TtyOperation for TtyConsoleDriverInner {
|
|||||||
// TODO: notify update
|
// TODO: notify update
|
||||||
return Ok(offset);
|
return Ok(offset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TtyOperation for TtyConsoleDriverInner {
|
||||||
|
fn install(&self, _driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
|
||||||
|
let tty_core = tty.core();
|
||||||
|
let mut vc_data = VIRT_CONSOLES[tty_core.index()].lock();
|
||||||
|
|
||||||
|
self.console.con_init(&mut vc_data, true)?;
|
||||||
|
if vc_data.complement_mask == 0 {
|
||||||
|
vc_data.complement_mask = if vc_data.color_mode { 0x7700 } else { 0x0800 };
|
||||||
|
}
|
||||||
|
vc_data.s_complement_mask = vc_data.complement_mask;
|
||||||
|
// vc_data.bytes_per_row = vc_data.cols << 1;
|
||||||
|
vc_data.index = tty_core.index();
|
||||||
|
vc_data.bottom = vc_data.rows;
|
||||||
|
vc_data.set_driver_funcs(Arc::downgrade(
|
||||||
|
&(self.console.clone() as Arc<dyn ConsoleSwitch>),
|
||||||
|
));
|
||||||
|
|
||||||
|
// todo: unicode字符集处理?
|
||||||
|
|
||||||
|
if vc_data.cols > VC_MAXCOL || vc_data.rows > VC_MAXROW {
|
||||||
|
return Err(SystemError::EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vc_data.init(None, None, true);
|
||||||
|
vc_data.update_attr();
|
||||||
|
|
||||||
|
let window_size = tty_core.window_size_upgradeable();
|
||||||
|
if window_size.col == 0 && window_size.row == 0 {
|
||||||
|
let mut window_size = window_size.upgrade();
|
||||||
|
window_size.col = vc_data.cols as u16;
|
||||||
|
window_size.row = vc_data.rows as u16;
|
||||||
|
kerror!("window_size {:?}", *window_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if vc_data.utf {
|
||||||
|
tty_core.termios_write().input_mode.insert(InputMode::IUTF8);
|
||||||
|
} else {
|
||||||
|
tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加入sysfs?
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_room(&self, _tty: &TtyCoreData) -> usize {
|
||||||
|
32768
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 参考: 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> {
|
||||||
|
let ret = self.do_write(tty, buf, nr);
|
||||||
|
self.flush_chars(tty);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn flush_chars(&self, tty: &TtyCoreData) {
|
fn flush_chars(&self, tty: &TtyCoreData) {
|
||||||
let mut vc_data = tty.vc_data_irqsave();
|
let mut vc_data = tty.vc_data_irqsave();
|
||||||
vc_data.set_cursor();
|
vc_data.set_cursor();
|
||||||
|
@ -7,7 +7,10 @@ use alloc::{
|
|||||||
use bitmap::{traits::BitMapOps, StaticBitmap};
|
use bitmap::{traits::BitMapOps, StaticBitmap};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::tty::{console::ConsoleSwitch, ConsoleFont, KDMode},
|
driver::{
|
||||||
|
serial::serial8250::send_to_default_serial8250_port,
|
||||||
|
tty::{console::ConsoleSwitch, ConsoleFont, KDMode},
|
||||||
|
},
|
||||||
libs::{font::FontDesc, rwlock::RwLock},
|
libs::{font::FontDesc, rwlock::RwLock},
|
||||||
process::Pid,
|
process::Pid,
|
||||||
};
|
};
|
||||||
@ -140,6 +143,7 @@ pub struct VirtualConsoleData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VirtualConsoleData {
|
impl VirtualConsoleData {
|
||||||
|
#[inline(never)]
|
||||||
pub fn new(num: usize) -> Self {
|
pub fn new(num: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: VirtualConsoleInfo::new(0, 0),
|
state: VirtualConsoleInfo::new(0, 0),
|
||||||
@ -264,7 +268,8 @@ impl VirtualConsoleData {
|
|||||||
self.pid = None;
|
self.pid = None;
|
||||||
self.vc_state = VirtualConsoleState::ESnormal;
|
self.vc_state = VirtualConsoleState::ESnormal;
|
||||||
self.reset_palette();
|
self.reset_palette();
|
||||||
self.cursor_type = VcCursor::CUR_UNDERLINE;
|
// self.cursor_type = VcCursor::CUR_UNDERLINE;
|
||||||
|
self.cursor_type = VcCursor::CUR_BLOCK;
|
||||||
|
|
||||||
self.default_attr();
|
self.default_attr();
|
||||||
self.update_attr();
|
self.update_attr();
|
||||||
@ -567,10 +572,10 @@ impl VirtualConsoleData {
|
|||||||
let min_y;
|
let min_y;
|
||||||
if self.origin_mode {
|
if self.origin_mode {
|
||||||
min_y = self.top;
|
min_y = self.top;
|
||||||
max_y = self.bottom;
|
max_y = self.bottom - 1;
|
||||||
} else {
|
} else {
|
||||||
min_y = 0;
|
min_y = 0;
|
||||||
max_y = self.rows;
|
max_y = self.rows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if y < min_y as i32 {
|
if y < min_y as i32 {
|
||||||
@ -596,9 +601,10 @@ impl VirtualConsoleData {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self
|
if self.is_visible()
|
||||||
.driver_funcs()
|
&& self
|
||||||
.con_scroll(self, self.top, self.bottom, dir, nr)
|
.driver_funcs()
|
||||||
|
.con_scroll(self, self.top, self.bottom, dir, nr)
|
||||||
{
|
{
|
||||||
// 如果成功
|
// 如果成功
|
||||||
return;
|
return;
|
||||||
@ -733,6 +739,7 @@ impl VirtualConsoleData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn do_getpars(&mut self, c: char) {
|
fn do_getpars(&mut self, c: char) {
|
||||||
if c == ';' && self.npar < (NPAR - 1) as u32 {
|
if c == ';' && self.npar < (NPAR - 1) as u32 {
|
||||||
self.npar += 1;
|
self.npar += 1;
|
||||||
@ -789,9 +796,11 @@ impl VirtualConsoleData {
|
|||||||
'n' => {
|
'n' => {
|
||||||
if self.private == Vt102_OP::EPecma {
|
if self.private == Vt102_OP::EPecma {
|
||||||
if self.par[0] == 5 {
|
if self.par[0] == 5 {
|
||||||
kwarn!("tty status report todo");
|
send_to_default_serial8250_port("tty status report todo".as_bytes());
|
||||||
|
panic!();
|
||||||
} else if self.par[0] == 6 {
|
} else if self.par[0] == 6 {
|
||||||
kwarn!("tty cursor report todo");
|
send_to_default_serial8250_port("tty cursor report todo".as_bytes());
|
||||||
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -847,7 +856,7 @@ impl VirtualConsoleData {
|
|||||||
self.par[0] += 1;
|
self.par[0] += 1;
|
||||||
}
|
}
|
||||||
self.gotoxy(
|
self.gotoxy(
|
||||||
(self.state.x - self.par[0] as usize) as i32,
|
self.state.x as i32 - self.par[0] as i32,
|
||||||
self.state.y as i32,
|
self.state.y as i32,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -863,7 +872,7 @@ impl VirtualConsoleData {
|
|||||||
if self.par[0] == 0 {
|
if self.par[0] == 0 {
|
||||||
self.par[0] += 1;
|
self.par[0] += 1;
|
||||||
}
|
}
|
||||||
self.gotoxy(0, (self.state.y - self.par[0] as usize) as i32);
|
self.gotoxy(0, self.state.y as i32 - self.par[0] as i32);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
'd' => {
|
'd' => {
|
||||||
@ -874,6 +883,7 @@ impl VirtualConsoleData {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
'H' | 'f' => {
|
'H' | 'f' => {
|
||||||
|
// MOVETO
|
||||||
if self.par[0] != 0 {
|
if self.par[0] != 0 {
|
||||||
self.par[0] -= 1;
|
self.par[0] -= 1;
|
||||||
}
|
}
|
||||||
@ -900,6 +910,18 @@ impl VirtualConsoleData {
|
|||||||
'P' => {
|
'P' => {
|
||||||
todo!("csi_P todo");
|
todo!("csi_P todo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 非ANSI标准,为ANSI拓展
|
||||||
|
'S' => {
|
||||||
|
self.scroll(ScrollDir::Up, self.par[0] as usize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
'T' => {
|
||||||
|
self.scroll(ScrollDir::Down, self.par[0] as usize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
'c' => {
|
'c' => {
|
||||||
if self.par[0] == 0 {
|
if self.par[0] == 0 {
|
||||||
kwarn!("respone ID todo");
|
kwarn!("respone ID todo");
|
||||||
@ -957,6 +979,7 @@ impl VirtualConsoleData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ## 处理Control Sequence Introducer(控制序列引导符) m字符
|
/// ## 处理Control Sequence Introducer(控制序列引导符) m字符
|
||||||
|
#[inline(never)]
|
||||||
fn csi_m(&mut self) {
|
fn csi_m(&mut self) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
loop {
|
loop {
|
||||||
@ -1236,6 +1259,7 @@ impl VirtualConsoleData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ## 处理终端控制字符
|
/// ## 处理终端控制字符
|
||||||
|
#[inline(never)]
|
||||||
pub(super) fn do_control(&mut self, ch: u32) {
|
pub(super) fn do_control(&mut self, ch: u32) {
|
||||||
// 首先检查是否处于 ANSI 控制字符串状态
|
// 首先检查是否处于 ANSI 控制字符串状态
|
||||||
if self.vc_state.is_ansi_control_string() && ch >= 8 && ch <= 13 {
|
if self.vc_state.is_ansi_control_string() && ch >= 8 && ch <= 13 {
|
||||||
@ -1512,6 +1536,7 @@ impl VirtualConsoleData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
pub(super) fn console_write_normal(
|
pub(super) fn console_write_normal(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut tc: u32,
|
mut tc: u32,
|
||||||
@ -1641,11 +1666,10 @@ impl VirtualConsoleData {
|
|||||||
fn do_update_region(&self, mut start: usize, mut count: usize) {
|
fn do_update_region(&self, mut start: usize, mut count: usize) {
|
||||||
let ret = self.driver_funcs().con_getxy(self, start);
|
let ret = self.driver_funcs().con_getxy(self, start);
|
||||||
let (mut x, mut y) = if ret.is_err() {
|
let (mut x, mut y) = if ret.is_err() {
|
||||||
let offset = start / 2;
|
(start % self.cols, start / self.cols)
|
||||||
(offset % self.cols, offset / self.cols)
|
|
||||||
} else {
|
} else {
|
||||||
let (tmp_start, tmp_x, tmp_y) = ret.unwrap();
|
let (_, tmp_x, tmp_y) = ret.unwrap();
|
||||||
start = tmp_start;
|
// start = tmp_start;
|
||||||
(tmp_x, tmp_y)
|
(tmp_x, tmp_y)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1697,6 +1721,8 @@ impl VirtualConsoleData {
|
|||||||
let ret = self.driver_funcs().con_getxy(self, start);
|
let ret = self.driver_funcs().con_getxy(self, start);
|
||||||
if ret.is_ok() {
|
if ret.is_ok() {
|
||||||
start = ret.unwrap().0;
|
start = ret.unwrap().0;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,6 +391,7 @@ impl ConsoleSwitch for BlittingFbConsole {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn con_scroll(
|
fn con_scroll(
|
||||||
&self,
|
&self,
|
||||||
vc_data: &mut VirtualConsoleData,
|
vc_data: &mut VirtualConsoleData,
|
||||||
@ -504,7 +505,30 @@ impl ConsoleSwitch for BlittingFbConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match scroll_mode {
|
match scroll_mode {
|
||||||
ScrollMode::Move => todo!(),
|
ScrollMode::Move => {
|
||||||
|
let start = top * vc_data.cols;
|
||||||
|
let end = bottom * vc_data.cols;
|
||||||
|
vc_data.screen_buf[start..end].rotate_right(count * vc_data.cols);
|
||||||
|
|
||||||
|
let _ = self.bmove(
|
||||||
|
vc_data,
|
||||||
|
top as i32,
|
||||||
|
0,
|
||||||
|
top as i32 + count as i32,
|
||||||
|
0,
|
||||||
|
(bottom - top - count) as u32,
|
||||||
|
vc_data.cols as u32,
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = self.con_clear(vc_data, top, 0, count, vc_data.cols);
|
||||||
|
|
||||||
|
let offset = vc_data.cols * count;
|
||||||
|
for i in vc_data.screen_buf[start..(start + offset)].iter_mut() {
|
||||||
|
*i = vc_data.erase_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
ScrollMode::PanMove => todo!(),
|
ScrollMode::PanMove => todo!(),
|
||||||
ScrollMode::WrapMove => todo!(),
|
ScrollMode::WrapMove => todo!(),
|
||||||
ScrollMode::Redraw => {
|
ScrollMode::Redraw => {
|
||||||
@ -554,7 +578,8 @@ impl FrameBufferConsole for BlittingFbConsole {
|
|||||||
sy * vc_data.font.height as i32,
|
sy * vc_data.font.height as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.fb().fb_copyarea(area)
|
self.fb().fb_copyarea(area);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(
|
fn clear(
|
||||||
|
@ -408,9 +408,7 @@ pub trait FrameBufferOps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 将数据从一处复制到另一处。
|
/// 将数据从一处复制到另一处。
|
||||||
fn fb_copyarea(&self, _data: CopyAreaData) -> Result<(), SystemError> {
|
fn fb_copyarea(&self, _data: CopyAreaData);
|
||||||
Err(SystemError::ENOSYS)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 将帧缓冲区的内容映射到用户空间。
|
/// 将帧缓冲区的内容映射到用户空间。
|
||||||
fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
|
fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
|
||||||
|
@ -418,86 +418,138 @@ impl FrameBufferOps for VesaFb {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fb_copyarea(&self, data: super::base::CopyAreaData) -> Result<(), SystemError> {
|
#[inline(never)]
|
||||||
|
fn fb_copyarea(&self, data: super::base::CopyAreaData) {
|
||||||
let bp = boot_params().read();
|
let bp = boot_params().read();
|
||||||
let base = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
|
let base = bp.screen_info.lfb_virt_base.unwrap();
|
||||||
let var = self.current_fb_var();
|
let var = self.current_fb_var();
|
||||||
|
|
||||||
if data.sx < 0
|
// 原区域或者目标区域全在屏幕外,则直接返回
|
||||||
|| data.sy < 0
|
if data.sx > var.xres as i32
|
||||||
|| data.sx as u32 > var.xres
|
|| data.sy > var.yres as i32
|
||||||
|| data.sx as u32 + data.width > var.xres
|
|| data.dx > var.xres as i32
|
||||||
|| data.sy as u32 > var.yres
|
|| data.dy > var.yres as i32
|
||||||
|| data.sy as u32 + data.height > var.yres
|
|| (data.sx + data.width as i32) < 0
|
||||||
|
|| (data.sy + data.height as i32) < 0
|
||||||
|
|| (data.dx + data.width as i32) < 0
|
||||||
|
|| (data.dy + data.height as i32) < 0
|
||||||
{
|
{
|
||||||
return Err(SystemError::EINVAL);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 求两个矩形可视范围交集
|
||||||
|
let (s_visiable_x, s_w) = if data.sx < 0 {
|
||||||
|
(0, (data.width - ((-data.sx) as u32)).min(var.xres))
|
||||||
|
} else {
|
||||||
|
let w = if data.sx as u32 + data.width > var.xres {
|
||||||
|
var.xres - data.sx as u32
|
||||||
|
} else {
|
||||||
|
data.width
|
||||||
|
};
|
||||||
|
|
||||||
|
(data.sx, w)
|
||||||
|
};
|
||||||
|
let (s_visiable_y, s_h) = if data.sy < 0 {
|
||||||
|
(0, (data.height - ((-data.sy) as u32).min(var.yres)))
|
||||||
|
} else {
|
||||||
|
let h = if data.sy as u32 + data.height > var.yres {
|
||||||
|
var.yres - data.sy as u32
|
||||||
|
} else {
|
||||||
|
data.height
|
||||||
|
};
|
||||||
|
|
||||||
|
(data.sy, h)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (d_visiable_x, d_w) = if data.dx < 0 {
|
||||||
|
(0, (data.width - ((-data.dx) as u32)).min(var.xres))
|
||||||
|
} else {
|
||||||
|
let w = if data.dx as u32 + data.width > var.xres {
|
||||||
|
var.xres - data.dx as u32
|
||||||
|
} else {
|
||||||
|
data.width
|
||||||
|
};
|
||||||
|
|
||||||
|
(data.dx, w)
|
||||||
|
};
|
||||||
|
let (d_visiable_y, d_h) = if data.dy < 0 {
|
||||||
|
(0, (data.height - ((-data.dy) as u32).min(var.yres)))
|
||||||
|
} else {
|
||||||
|
let h = if data.dy as u32 + data.height > var.yres {
|
||||||
|
var.yres - data.dy as u32
|
||||||
|
} else {
|
||||||
|
data.height
|
||||||
|
};
|
||||||
|
|
||||||
|
(data.dy, h)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 可视范围无交集
|
||||||
|
if !(d_h + s_h > data.height && s_w + d_w > data.width) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可视区域左上角相对于矩形的坐标
|
||||||
|
let s_relative_x = s_visiable_x - data.sx;
|
||||||
|
let s_relative_y = s_visiable_y - data.sy;
|
||||||
|
let d_relative_x = d_visiable_x - data.dx;
|
||||||
|
let d_relative_y = d_visiable_y - data.dy;
|
||||||
|
|
||||||
|
let visiable_x = s_relative_x.max(d_relative_x);
|
||||||
|
let visiable_y = s_relative_y.max(d_relative_y);
|
||||||
|
let visiable_h = d_h + s_h - data.height;
|
||||||
|
let visiable_w = d_w + s_w - data.width;
|
||||||
|
|
||||||
|
let s_real_x = (visiable_x + data.sx) as u32;
|
||||||
|
let s_real_y = (visiable_y + data.sy) as u32;
|
||||||
|
let d_real_x = (visiable_x + data.dx) as u32;
|
||||||
|
let d_real_y = (visiable_y + data.dy) as u32;
|
||||||
|
|
||||||
let bytes_per_pixel = var.bits_per_pixel >> 3;
|
let bytes_per_pixel = var.bits_per_pixel >> 3;
|
||||||
let bytes_per_line = var.xres * bytes_per_pixel;
|
let bytes_per_line = var.xres * bytes_per_pixel;
|
||||||
|
|
||||||
let sy = data.sy as u32;
|
let src =
|
||||||
let sx = data.sx as u32;
|
base + VirtAddr::new((s_real_y * bytes_per_line + s_real_x * bytes_per_pixel) as usize);
|
||||||
|
|
||||||
let dst = {
|
let dst =
|
||||||
let mut dst = base;
|
base + VirtAddr::new((d_real_y * bytes_per_line + d_real_x * bytes_per_pixel) as usize);
|
||||||
if data.dy < 0 {
|
|
||||||
dst -= VirtAddr::new((((-data.dy) as u32) * bytes_per_line) as usize);
|
|
||||||
} else {
|
|
||||||
dst += VirtAddr::new(((data.dy as u32) * bytes_per_line) as usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.dx > 0 && (data.dx as u32) < var.xres {
|
let size = (visiable_h * visiable_w) as usize;
|
||||||
dst += VirtAddr::new(((data.dx as u32) * bytes_per_pixel) as usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
dst
|
|
||||||
};
|
|
||||||
let src = base + VirtAddr::new((sy * bytes_per_line + sx * bytes_per_pixel) as usize);
|
|
||||||
|
|
||||||
match bytes_per_pixel {
|
match bytes_per_pixel {
|
||||||
4 => {
|
4 => {
|
||||||
// 32bpp
|
// 32bpp
|
||||||
let mut dst = dst.as_ptr::<u32>();
|
let mut dst = dst.as_ptr::<u32>();
|
||||||
let mut src = src.as_ptr::<u32>();
|
let mut src = src.as_ptr::<u32>();
|
||||||
|
let line_offset = var.xres as usize;
|
||||||
|
|
||||||
for y in 0..data.height as usize {
|
if s_real_x > d_real_x {
|
||||||
if (data.dy + y as i32) < 0 || (data.dy + y as i32) > var.yres as i32 {
|
// 如果src在dst下方,则可以直接拷贝不会出现指针覆盖
|
||||||
unsafe {
|
unsafe {
|
||||||
// core::ptr::copy(src, dst, data.width as usize);
|
for _ in 0..visiable_h {
|
||||||
src = src.add(var.xres as usize);
|
core::ptr::copy(src, dst, visiable_w as usize);
|
||||||
dst = dst.add(var.xres as usize);
|
src = src.add(line_offset);
|
||||||
|
dst = dst.add(visiable_w as usize);
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if data.dx < 0 {
|
} else {
|
||||||
if ((-data.dx) as u32) < data.width {
|
let mut tmp: Vec<u32> = Vec::with_capacity(size);
|
||||||
unsafe {
|
tmp.resize(size, 0);
|
||||||
core::ptr::copy(
|
let mut tmp_ptr = tmp.as_mut_ptr();
|
||||||
src.add((-data.dx) as usize),
|
|
||||||
dst,
|
// 这里是一个可以优化的点,现在为了避免指针拷贝时覆盖,统一先拷贝进入buf再拷贝到dst
|
||||||
(data.width as usize) - (-data.dx) as usize,
|
unsafe {
|
||||||
);
|
for _ in 0..visiable_h {
|
||||||
src = src.add(var.xres as usize);
|
core::ptr::copy(src, tmp_ptr, visiable_w as usize);
|
||||||
dst = dst.add(var.xres as usize);
|
src = src.add(line_offset);
|
||||||
}
|
tmp_ptr = tmp_ptr.add(visiable_w as usize);
|
||||||
}
|
}
|
||||||
} else if data.dx as u32 + data.width > var.xres {
|
|
||||||
if (data.dx as u32) < var.xres {
|
tmp_ptr = tmp_ptr.sub(size);
|
||||||
unsafe {
|
for _ in 0..visiable_h {
|
||||||
core::ptr::copy(src, dst, (var.xres - data.dx as u32) as usize);
|
core::ptr::copy(tmp_ptr, dst, visiable_w as usize);
|
||||||
src = src.add(var.xres as usize);
|
dst = dst.add(line_offset);
|
||||||
dst = dst.add(var.xres as usize);
|
tmp_ptr = tmp_ptr.add(visiable_w as usize);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i in 0..data.width as usize {
|
|
||||||
unsafe { *(dst.add(i)) = *(src.add(i)) }
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
// core::ptr::copy(src, dst, data.width as usize);
|
|
||||||
src = src.add(var.xres as usize);
|
|
||||||
dst = dst.add(var.xres as usize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,7 +558,6 @@ impl FrameBufferOps for VesaFb {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +484,18 @@ impl File {
|
|||||||
let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap();
|
let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap();
|
||||||
return inode.inner().lock().add_epoll(epitem);
|
return inode.inner().lock().add_epoll(epitem);
|
||||||
}
|
}
|
||||||
_ => return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP),
|
_ => {
|
||||||
|
let r = self.inode.ioctl(
|
||||||
|
EventPoll::ADD_EPOLLITEM,
|
||||||
|
&epitem as *const Arc<EPollItem> as usize,
|
||||||
|
&self.private_data,
|
||||||
|
);
|
||||||
|
if r.is_err() {
|
||||||
|
return Err(SystemError::ENOSYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,6 +369,11 @@ impl IndexNode for MountFSInode {
|
|||||||
fn special_node(&self) -> Option<super::SpecialNodeData> {
|
fn special_node(&self) -> Option<super::SpecialNodeData> {
|
||||||
self.inner_inode.special_node()
|
self.inner_inode.special_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
|
||||||
|
self.inner_inode.poll(private_data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileSystem for MountFS {
|
impl FileSystem for MountFS {
|
||||||
|
@ -86,7 +86,7 @@ impl Signal {
|
|||||||
return Err(SystemError::EINVAL);
|
return Err(SystemError::EINVAL);
|
||||||
}
|
}
|
||||||
// kdebug!("force send={}", force_send);
|
// kdebug!("force send={}", force_send);
|
||||||
let pcb_info = pcb.sig_info();
|
let pcb_info = pcb.sig_info_irqsave();
|
||||||
let pending = if matches!(pt, PidType::PID) {
|
let pending = if matches!(pt, PidType::PID) {
|
||||||
pcb_info.sig_shared_pending()
|
pcb_info.sig_shared_pending()
|
||||||
} else {
|
} else {
|
||||||
@ -189,7 +189,11 @@ impl Signal {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
|
fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
|
||||||
// 如果改进程屏蔽了这个signal,则不能接收
|
// 如果改进程屏蔽了这个signal,则不能接收
|
||||||
if pcb.sig_info().sig_block().contains(self.clone().into()) {
|
if pcb
|
||||||
|
.sig_info_irqsave()
|
||||||
|
.sig_block()
|
||||||
|
.contains(self.clone().into())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +213,7 @@ impl Signal {
|
|||||||
// todo: 检查目标进程是否正在一个cpu上执行,如果是,则返回true,否则继续检查下一项
|
// todo: 检查目标进程是否正在一个cpu上执行,如果是,则返回true,否则继续检查下一项
|
||||||
|
|
||||||
// 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true
|
// 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true
|
||||||
if pcb.sig_info().sig_pending().signal().bits() == 0 {
|
if pcb.sig_info_irqsave().sig_pending().signal().bits() == 0 {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -263,7 +267,11 @@ impl Signal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 一个被阻塞了的信号肯定是要被处理的
|
// 一个被阻塞了的信号肯定是要被处理的
|
||||||
if pcb.sig_info().sig_block().contains(self.into_sigset()) {
|
if pcb
|
||||||
|
.sig_info_irqsave()
|
||||||
|
.sig_block()
|
||||||
|
.contains(self.into_sigset())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !pcb.sig_struct().handlers[self.clone() as usize - 1].is_ignore();
|
return !pcb.sig_struct().handlers[self.clone() as usize - 1].is_ignore();
|
||||||
@ -430,7 +438,7 @@ pub fn set_current_sig_blocked(new_set: &mut SigSet) {
|
|||||||
如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
|
如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
|
||||||
请注意,一个进程的sig_blocked字段不能被其他进程修改!
|
请注意,一个进程的sig_blocked字段不能被其他进程修改!
|
||||||
*/
|
*/
|
||||||
if pcb.sig_info().sig_block().eq(new_set) {
|
if pcb.sig_info_irqsave().sig_block().eq(new_set) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
|||||||
io_mfence();
|
io_mfence();
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
char buf[4096]; // vsprintf()的缓冲区
|
static char buf[4096]; // vsprintf()的缓冲区
|
||||||
int len = vsprintf(buf, fmt, args);
|
int len = vsprintf(buf, fmt, args);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
@ -218,6 +218,23 @@ impl<T> RwLock<T> {
|
|||||||
return r;
|
return r;
|
||||||
} //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
|
} //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[inline]
|
||||||
|
pub fn try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>> {
|
||||||
|
ProcessManager::preempt_disable();
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
let r = self.inner_try_write().map(|mut g| {
|
||||||
|
g.irq_guard = Some(irq_guard);
|
||||||
|
g
|
||||||
|
});
|
||||||
|
if r.is_none() {
|
||||||
|
ProcessManager::preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {
|
fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {
|
||||||
|
@ -52,6 +52,8 @@ pub struct EventPoll {
|
|||||||
|
|
||||||
impl EventPoll {
|
impl EventPoll {
|
||||||
pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32);
|
pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32);
|
||||||
|
/// 用于获取inode中的epitem队列
|
||||||
|
pub const ADD_EPOLLITEM: u32 = 0x7965;
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
epoll_wq: WaitQueue::INIT,
|
epoll_wq: WaitQueue::INIT,
|
||||||
@ -462,7 +464,7 @@ impl EventPoll {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果有未处理的信号则返回错误
|
// 如果有未处理的信号则返回错误
|
||||||
if current_pcb.sig_info().sig_pending().signal().bits() != 0 {
|
if current_pcb.sig_info_irqsave().sig_pending().signal().bits() != 0 {
|
||||||
return Err(SystemError::EINTR);
|
return Err(SystemError::EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,12 +363,12 @@ impl ProcessManager {
|
|||||||
|
|
||||||
// 设置clear_child_tid,在线程结束时将其置0以通知父进程
|
// 设置clear_child_tid,在线程结束时将其置0以通知父进程
|
||||||
if clone_flags.contains(CloneFlags::CLONE_CHILD_CLEARTID) {
|
if clone_flags.contains(CloneFlags::CLONE_CHILD_CLEARTID) {
|
||||||
pcb.thread.write().clear_child_tid = Some(clone_args.child_tid);
|
pcb.thread.write_irqsave().clear_child_tid = Some(clone_args.child_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置child_tid,意味着子线程能够知道自己的id
|
// 设置child_tid,意味着子线程能够知道自己的id
|
||||||
if clone_flags.contains(CloneFlags::CLONE_CHILD_SETTID) {
|
if clone_flags.contains(CloneFlags::CLONE_CHILD_SETTID) {
|
||||||
pcb.thread.write().set_child_tid = Some(clone_args.child_tid);
|
pcb.thread.write_irqsave().set_child_tid = Some(clone_args.child_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将子进程/线程的id存储在用户态传进的地址中
|
// 将子进程/线程的id存储在用户态传进的地址中
|
||||||
@ -424,13 +424,14 @@ impl ProcessManager {
|
|||||||
|
|
||||||
// 设置线程组id、组长
|
// 设置线程组id、组长
|
||||||
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
||||||
pcb.thread.write().group_leader = current_pcb.thread.read().group_leader.clone();
|
pcb.thread.write_irqsave().group_leader =
|
||||||
|
current_pcb.thread.read_irqsave().group_leader.clone();
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
|
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
|
||||||
(*ptr).tgid = current_pcb.tgid;
|
(*ptr).tgid = current_pcb.tgid;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pcb.thread.write().group_leader = Arc::downgrade(&pcb);
|
pcb.thread.write_irqsave().group_leader = Arc::downgrade(&pcb);
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
|
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
|
||||||
(*ptr).tgid = pcb.tgid;
|
(*ptr).tgid = pcb.tgid;
|
||||||
@ -439,12 +440,13 @@ impl ProcessManager {
|
|||||||
|
|
||||||
// CLONE_PARENT re-uses the old parent
|
// CLONE_PARENT re-uses the old parent
|
||||||
if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) {
|
if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) {
|
||||||
*pcb.real_parent_pcb.write() = current_pcb.real_parent_pcb.read().clone();
|
*pcb.real_parent_pcb.write_irqsave() =
|
||||||
|
current_pcb.real_parent_pcb.read_irqsave().clone();
|
||||||
|
|
||||||
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
if clone_flags.contains(CloneFlags::CLONE_THREAD) {
|
||||||
pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
|
pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
|
||||||
} else {
|
} else {
|
||||||
let leader = current_pcb.thread.read().group_leader();
|
let leader = current_pcb.thread.read_irqsave().group_leader();
|
||||||
if unlikely(leader.is_none()) {
|
if unlikely(leader.is_none()) {
|
||||||
panic!(
|
panic!(
|
||||||
"fork: Failed to get leader of current process, current pid: [{:?}]",
|
"fork: Failed to get leader of current process, current pid: [{:?}]",
|
||||||
@ -459,7 +461,7 @@ impl ProcessManager {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 新创建的进程,设置其父进程为当前进程
|
// 新创建的进程,设置其父进程为当前进程
|
||||||
*pcb.real_parent_pcb.write() = Arc::downgrade(¤t_pcb);
|
*pcb.real_parent_pcb.write_irqsave() = Arc::downgrade(¤t_pcb);
|
||||||
pcb.exit_signal
|
pcb.exit_signal
|
||||||
.store(clone_args.exit_signal, Ordering::SeqCst);
|
.store(clone_args.exit_signal, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ impl ProcessManager {
|
|||||||
.adopt_childen()
|
.adopt_childen()
|
||||||
.unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}"))
|
.unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}"))
|
||||||
};
|
};
|
||||||
let r = current.parent_pcb.read().upgrade();
|
let r = current.parent_pcb.read_irqsave().upgrade();
|
||||||
if r.is_none() {
|
if r.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ impl ProcessManager {
|
|||||||
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
|
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
|
||||||
|
|
||||||
// 进行进程退出后的工作
|
// 进行进程退出后的工作
|
||||||
let thread = pcb.thread.write();
|
let thread = pcb.thread.write_irqsave();
|
||||||
if let Some(addr) = thread.set_child_tid {
|
if let Some(addr) = thread.set_child_tid {
|
||||||
unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
|
unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
|
||||||
}
|
}
|
||||||
@ -668,7 +668,7 @@ impl ProcessControlBlock {
|
|||||||
|
|
||||||
// 将当前pcb加入父进程的子进程哈希表中
|
// 将当前pcb加入父进程的子进程哈希表中
|
||||||
if pcb.pid() > Pid(1) {
|
if pcb.pid() > Pid(1) {
|
||||||
if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() {
|
if let Some(ppcb_arc) = pcb.parent_pcb.read_irqsave().upgrade() {
|
||||||
let mut children = ppcb_arc.children.write_irqsave();
|
let mut children = ppcb_arc.children.write_irqsave();
|
||||||
children.push(pcb.pid());
|
children.push(pcb.pid());
|
||||||
} else {
|
} else {
|
||||||
@ -718,7 +718,7 @@ impl ProcessControlBlock {
|
|||||||
/// 否则会导致死锁
|
/// 否则会导致死锁
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
|
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
|
||||||
return self.basic.read();
|
return self.basic.read_irqsave();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -841,17 +841,13 @@ impl ProcessControlBlock {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sig_info(&self) -> RwLockReadGuard<ProcessSignalInfo> {
|
|
||||||
self.sig_info.read()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sig_info_irqsave(&self) -> RwLockReadGuard<ProcessSignalInfo> {
|
pub fn sig_info_irqsave(&self) -> RwLockReadGuard<ProcessSignalInfo> {
|
||||||
self.sig_info.read_irqsave()
|
self.sig_info.read_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_siginfo(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> {
|
pub fn try_siginfo_irqsave(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> {
|
||||||
for _ in 0..times {
|
for _ in 0..times {
|
||||||
if let Some(r) = self.sig_info.try_read() {
|
if let Some(r) = self.sig_info.try_read_irqsave() {
|
||||||
return Some(r);
|
return Some(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -865,7 +861,7 @@ impl ProcessControlBlock {
|
|||||||
|
|
||||||
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
|
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
|
||||||
for _ in 0..times {
|
for _ in 0..times {
|
||||||
if let Some(r) = self.sig_info.try_write() {
|
if let Some(r) = self.sig_info.try_write_irqsave() {
|
||||||
return Some(r);
|
return Some(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,10 +870,10 @@ impl ProcessControlBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> {
|
pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> {
|
||||||
self.sig_struct.lock()
|
self.sig_struct.lock_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_sig_struct_irq(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> {
|
pub fn try_sig_struct_irqsave(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> {
|
||||||
for _ in 0..times {
|
for _ in 0..times {
|
||||||
if let Ok(r) = self.sig_struct.try_lock_irqsave() {
|
if let Ok(r) = self.sig_struct.try_lock_irqsave() {
|
||||||
return Some(r);
|
return Some(r);
|
||||||
@ -894,13 +890,19 @@ impl ProcessControlBlock {
|
|||||||
|
|
||||||
impl Drop for ProcessControlBlock {
|
impl Drop for ProcessControlBlock {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
// kdebug!("drop: {:?}", self.pid);
|
||||||
// 在ProcFS中,解除进程的注册
|
// 在ProcFS中,解除进程的注册
|
||||||
procfs_unregister_pid(self.pid())
|
procfs_unregister_pid(self.pid())
|
||||||
.unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
|
.unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
|
||||||
|
|
||||||
if let Some(ppcb) = self.parent_pcb.read().upgrade() {
|
if let Some(ppcb) = self.parent_pcb.read_irqsave().upgrade() {
|
||||||
ppcb.children.write().retain(|pid| *pid != self.pid());
|
ppcb.children
|
||||||
|
.write_irqsave()
|
||||||
|
.retain(|pid| *pid != self.pid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop(irq_guard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,11 +202,11 @@ impl Syscall {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if flags.contains(CloneFlags::CLONE_VFORK) {
|
if flags.contains(CloneFlags::CLONE_VFORK) {
|
||||||
pcb.thread.write().vfork_done = Some(vfork.clone());
|
pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if pcb.thread.read().set_child_tid.is_some() {
|
if pcb.thread.read_irqsave().set_child_tid.is_some() {
|
||||||
let addr = pcb.thread.read().set_child_tid.unwrap();
|
let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
|
||||||
let mut writer =
|
let mut writer =
|
||||||
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
|
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
|
||||||
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
|
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
|
||||||
@ -234,7 +234,7 @@ impl Syscall {
|
|||||||
.map_err(|_| SystemError::EFAULT)?;
|
.map_err(|_| SystemError::EFAULT)?;
|
||||||
|
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr));
|
pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
|
||||||
Ok(pcb.pid.0)
|
Ok(pcb.pid.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user