mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: set stdio to null when orphan is true (#229)
This commit is contained in:
parent
d3d3462b5e
commit
5584ba4844
2 changed files with 53 additions and 36 deletions
65
core/src/external/shell.rs
vendored
65
core/src/external/shell.rs
vendored
|
|
@ -15,37 +15,44 @@ impl ShellOpt {
|
||||||
self.piped = true;
|
self.piped = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn stdio(&self) -> Stdio {
|
||||||
|
if self.orphan {
|
||||||
|
Stdio::null()
|
||||||
|
} else if self.piped {
|
||||||
|
Stdio::piped()
|
||||||
|
} else {
|
||||||
|
Stdio::inherit()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shell(opt: ShellOpt) -> Result<Child> {
|
pub fn shell(opt: ShellOpt) -> Result<Child> {
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(unix)]
|
||||||
{
|
return Ok(
|
||||||
Ok(
|
Command::new("sh")
|
||||||
Command::new("sh")
|
.arg("-c")
|
||||||
.arg("-c")
|
.stdin(opt.stdio())
|
||||||
.arg(opt.cmd)
|
.stdout(opt.stdio())
|
||||||
.arg("") // $0 is the command name
|
.stderr(opt.stdio())
|
||||||
.args(opt.args)
|
.arg(opt.cmd)
|
||||||
.stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.arg("") // $0 is the command name
|
||||||
.stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.args(opt.args)
|
||||||
.stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.kill_on_drop(!opt.orphan)
|
||||||
.kill_on_drop(!opt.orphan)
|
.spawn()?,
|
||||||
.spawn()?,
|
);
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(windows)]
|
||||||
{
|
return Ok(
|
||||||
Ok(
|
Command::new("cmd")
|
||||||
Command::new("cmd")
|
.stdin(opt.stdio())
|
||||||
.arg("/C")
|
.stdout(opt.stdio())
|
||||||
.arg(opt.cmd)
|
.stderr(opt.stdio())
|
||||||
.args(opt.args)
|
.arg("/C")
|
||||||
.stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.arg(opt.cmd)
|
||||||
.stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.args(opt.args)
|
||||||
.stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
|
.kill_on_drop(true)
|
||||||
.kill_on_drop(true)
|
.spawn()?,
|
||||||
.spawn()?,
|
);
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use std::{ffi::OsString, mem};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}};
|
use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}};
|
||||||
use tracing::trace;
|
|
||||||
|
|
||||||
use crate::{emit, external::{self, ShellOpt}, tasks::TaskOp, BLOCKER};
|
use crate::{emit, external::{self, ShellOpt}, tasks::TaskOp, BLOCKER};
|
||||||
|
|
||||||
|
|
@ -41,26 +40,37 @@ impl Process {
|
||||||
fn done(&self, id: usize) -> Result<()> { Ok(self.sch.send(TaskOp::Done(id))?) }
|
fn done(&self, id: usize) -> Result<()> { Ok(self.sch.send(TaskOp::Done(id))?) }
|
||||||
|
|
||||||
pub(crate) async fn open(&self, mut task: ProcessOpOpen) -> Result<()> {
|
pub(crate) async fn open(&self, mut task: ProcessOpOpen) -> Result<()> {
|
||||||
|
let opt = ShellOpt::from(&mut task);
|
||||||
if task.block {
|
if task.block {
|
||||||
let _guard = BLOCKER.acquire().await.unwrap();
|
let _guard = BLOCKER.acquire().await.unwrap();
|
||||||
emit!(Stop(true)).await;
|
emit!(Stop(true)).await;
|
||||||
|
|
||||||
match external::shell(ShellOpt::from(&mut task)) {
|
match external::shell(opt) {
|
||||||
Ok(mut child) => {
|
Ok(mut child) => {
|
||||||
child.wait().await.ok();
|
child.wait().await.ok();
|
||||||
|
self.done(task.id)?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
trace!("Failed to spawn process: {e}");
|
self.sch.send(TaskOp::New(task.id, 0))?;
|
||||||
|
self.log(task.id, format!("Failed to spawn process: {e}"))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit!(Stop(false)).await;
|
return Ok(emit!(Stop(false)).await);
|
||||||
|
}
|
||||||
|
|
||||||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
if task.orphan {
|
||||||
return self.done(task.id);
|
match external::shell(opt) {
|
||||||
|
Ok(_) => self.done(task.id)?,
|
||||||
|
Err(e) => {
|
||||||
|
self.sch.send(TaskOp::New(task.id, 0))?;
|
||||||
|
self.log(task.id, format!("Failed to spawn process: {e}"))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sch.send(TaskOp::New(task.id, 0))?;
|
self.sch.send(TaskOp::New(task.id, 0))?;
|
||||||
let mut child = external::shell(ShellOpt::from(&mut task).with_piped())?;
|
let mut child = external::shell(opt.with_piped())?;
|
||||||
|
|
||||||
let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines();
|
let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines();
|
||||||
let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();
|
let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue