Skip to content
Merged
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
63 changes: 17 additions & 46 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::{
sync::{Arc, Mutex},
};

use nix::unistd::{read, write};
use regex::Regex;

use crate::env::EnvManager;
Expand Down Expand Up @@ -408,7 +407,7 @@ impl Pipeline {
internal = true;

// 用于同步父子进程的tty setpgrp行为的管道
let (rfd, wfd) = nix::unistd::pipe().expect("Failed to create pipe");
let (rfd, _wfd) = nix::unistd::pipe().expect("Failed to create pipe");

// child_pid
let child_pid = if self.backend {
Expand All @@ -419,24 +418,6 @@ impl Pipeline {

// 为子进程或前台运行
if child_pid == 0 {
if self.backend {
drop(wfd);
let mut tmpbf = [0u8; 1];
loop {
let x = read(rfd.as_raw_fd(), &mut tmpbf)
.expect("Failed to read from pipe");
if x > 0 {
break;
} else {
std::thread::sleep(std::time::Duration::from_millis(30));
}
}
drop(rfd);
} else {
drop(rfd);
drop(wfd);
}

let mut old_stdin: Option<i32> = None;
let mut old_stdout: Option<i32> = None;

Expand Down Expand Up @@ -528,12 +509,6 @@ impl Pipeline {
// 当前进程为父进程
drop(rfd);
unsafe {
// 设置前台进程
libc::tcsetpgrp(libc::STDIN_FILENO, child_pid);
// 让子进程开始运行
write(wfd.as_fd(), &[1]).expect("Failed to write to pipe");
drop(wfd);

let mut status = 0;
err = match libc::waitpid(child_pid, &mut status, 0) {
-1 => Some(ExecuteErrorType::ExecuteFailed),
Expand All @@ -549,16 +524,6 @@ impl Pipeline {
err = Some(ExecuteErrorType::ProcessTerminated);
}
}

// 还原前台进程
let r = libc::tcsetpgrp(libc::STDIN_FILENO, std::process::id() as i32);
if r == -1 {
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
println!(
"[novashell error]: restore tty pgrp: tcsetpgrp failed: {}",
errno
);
}
}
} else {
err = Some(ExecuteErrorType::ExecuteFailed)
Expand Down Expand Up @@ -658,12 +623,16 @@ impl Pipeline {

// println!("exec command: {child_command:#?}");

unsafe {
if !self.backend {
// 设置前台进程
libc::tcsetpgrp(libc::STDIN_FILENO, child.id() as i32);
};
unsafe {
libc::tcsetpgrp(libc::STDIN_FILENO, child.id() as i32);
};
}

// 让子进程继续执行
write(wfd.as_fd(), &[1u8]).expect("Failed to write to pipe");
nix::unistd::write(wfd.as_fd(), &[1u8])
.expect("Failed to write to pipe");
drop(wfd);
match child.wait() {
Ok(exit_status) => match exit_status.code() {
Expand All @@ -679,12 +648,14 @@ impl Pipeline {
Err(_) => err = Some(ExecuteErrorType::ExecuteFailed),
};

// 还原前台进程
unsafe {
libc::tcsetpgrp(
libc::STDIN_FILENO,
std::process::id() as i32,
);
if !self.backend {
// 还原前台进程
unsafe {
libc::tcsetpgrp(
libc::STDIN_FILENO,
std::process::id() as i32,
);
}
}

children.push(child);
Expand Down