Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions kernel/src/driver/tty/tty_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,15 @@ impl IndexNode for TtyDevice {
{
let pcb = ProcessManager::current_pcb();
let pcb_tty = pcb.sig_info_irqsave().tty();

let cond1 = pcb_tty.is_none();
let _cond2 = tty.core().contorl_info_irqsave().session.is_none();

// 注意!!这里为了debug,临时把cond2的判断去掉了,其实要cond1 && cond2才对
if cond1 {
let is_session_leader = pcb.sig_info_irqsave().is_session_leader;
let tty_session_is_none = tty.core().contorl_info_irqsave().session.is_none();
// Linux tty_open_proc_set_tty 语义:必须是会话首进程、尚无 controlling tty、
// tty 当前未被会话占用,且本次 open 具备读权限(不是 O_WRONLY)。
if is_session_leader
&& pcb_tty.is_none()
&& tty_session_is_none
&& !mode.is_write_only()
{
TtyJobCtrlManager::proc_set_tty(tty);
}
}
Expand Down
11 changes: 5 additions & 6 deletions kernel/src/driver/tty/tty_job_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl TtyJobCtrlManager {
pub fn remove_session_tty(tty: &Arc<TtyCore>) {
let mut ctrl = tty.core().contorl_info_irqsave();
ctrl.session = None;
ctrl.pgid = None;
}

/// ### 检查tty
Expand Down Expand Up @@ -176,9 +177,8 @@ impl TtyJobCtrlManager {
fn tiocgpgrp(real_tty: Arc<TtyCore>, arg: usize) -> Result<usize, SystemError> {
// log::debug!("job_ctrl_ioctl: TIOCGPGRP");
let current = ProcessManager::current_pcb();
if current.sig_info_irqsave().tty().is_some()
&& !Arc::ptr_eq(&current.sig_info_irqsave().tty().unwrap(), &real_tty)
{
let current_tty = current.sig_info_irqsave().tty();
if current_tty.is_none() || !Arc::ptr_eq(&current_tty.unwrap(), &real_tty) {
return Err(SystemError::ENOTTY);
}

Expand All @@ -200,9 +200,8 @@ impl TtyJobCtrlManager {
fn tiocgsid(real_tty: Arc<TtyCore>, arg: usize) -> Result<usize, SystemError> {
// log::debug!("job_ctrl_ioctl: TIOCGSID");
let current = ProcessManager::current_pcb();
if current.sig_info_irqsave().tty().is_some()
&& !Arc::ptr_eq(&current.sig_info_irqsave().tty().unwrap(), &real_tty)
{
let current_tty = current.sig_info_irqsave().tty();
if current_tty.is_none() || !Arc::ptr_eq(&current_tty.unwrap(), &real_tty) {
return Err(SystemError::ENOTTY);
}

Expand Down
17 changes: 11 additions & 6 deletions kernel/src/process/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ pub fn stdio_init() -> Result<(), SystemError> {
.lookup(&tty_path)
.unwrap_or_else(|_| panic!("Init stdio: can't find {}", tty_path));

let stdin =
File::new(tty_inode.clone(), FileFlags::O_RDONLY).expect("Init stdio: can't create stdin");
let stdout =
File::new(tty_inode.clone(), FileFlags::O_WRONLY).expect("Init stdio: can't create stdout");
let stderr = File::new(tty_inode.clone(), FileFlags::O_WRONLY | FileFlags::O_SYNC)
.expect("Init stdio: can't create stderr");
// Linux 语义对齐:init(pid=1) 的早期 stdio 绑定不应自动获得 controlling tty。
// 否则会占住 tty session,影响后续用户态会话通过 TIOCSCTTY 建立控制终端。
let stdin = File::new(tty_inode.clone(), FileFlags::O_RDONLY | FileFlags::O_NOCTTY)
.expect("Init stdio: can't create stdin");
let stdout = File::new(tty_inode.clone(), FileFlags::O_WRONLY | FileFlags::O_NOCTTY)
.expect("Init stdio: can't create stdout");
let stderr = File::new(
tty_inode.clone(),
FileFlags::O_WRONLY | FileFlags::O_SYNC | FileFlags::O_NOCTTY,
)
.expect("Init stdio: can't create stderr");

/*
按照规定,进程的文件描述符数组的前三个位置,分别是stdin, stdout, stderr
Expand Down
50 changes: 50 additions & 0 deletions user/apps/c_unitest/test_tcgetpgrp_no_ctty.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void) {
if (!isatty(STDIN_FILENO)) {
printf("[SKIP] stdin is not a tty, skip tcgetpgrp no-ctty test\n");
return 0;
}

pid_t pid = fork();
if (pid < 0) {
perror("fork");
return 1;
}

if (pid == 0) {
if (setsid() < 0) {
perror("setsid");
_exit(2);
}

errno = 0;
pid_t pgrp = tcgetpgrp(STDIN_FILENO);
if (pgrp == -1 && errno == ENOTTY) {
printf("[PASS] tcgetpgrp without controlling tty returns ENOTTY\n");
_exit(0);
}

fprintf(stderr,
"[FAIL] tcgetpgrp without controlling tty: ret=%d errno=%d\n",
(int)pgrp, errno);
_exit(3);
}

int status = 0;
if (waitpid(pid, &status, 0) < 0) {
perror("waitpid");
return 1;
}

if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}

fprintf(stderr, "[FAIL] child did not exit normally\n");
return 1;
}
2 changes: 1 addition & 1 deletion user/sysconfig/etc/inittab
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# /etc/inittab
::sysinit:busybox sh /etc/init.d/rcS # 系统初始化脚本

::askfirst:/bin/busybox login -f root
::askfirst:-/bin/busybox login -f root

# /etc/inittab - 根据源码弄出来的默认inittab
# https://code.dragonos.org.cn/xref/busybox-1.35.0/init/init.c#679
Expand Down
Loading