From 5584ba48442c780d5a2b2c49419b19ee746c0b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Sat, 30 Sep 2023 20:43:47 +0800 Subject: [PATCH] fix: set stdio to null when `orphan` is true (#229) --- core/src/external/shell.rs | 65 +++++++++++++++++-------------- core/src/tasks/workers/process.rs | 24 ++++++++---- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/core/src/external/shell.rs b/core/src/external/shell.rs index 2ca8f185..4285c7a7 100644 --- a/core/src/external/shell.rs +++ b/core/src/external/shell.rs @@ -15,37 +15,44 @@ impl ShellOpt { self.piped = true; 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 { - #[cfg(not(target_os = "windows"))] - { - Ok( - Command::new("sh") - .arg("-c") - .arg(opt.cmd) - .arg("") // $0 is the command name - .args(opt.args) - .stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .kill_on_drop(!opt.orphan) - .spawn()?, - ) - } + #[cfg(unix)] + return Ok( + Command::new("sh") + .arg("-c") + .stdin(opt.stdio()) + .stdout(opt.stdio()) + .stderr(opt.stdio()) + .arg(opt.cmd) + .arg("") // $0 is the command name + .args(opt.args) + .kill_on_drop(!opt.orphan) + .spawn()?, + ); - #[cfg(target_os = "windows")] - { - Ok( - Command::new("cmd") - .arg("/C") - .arg(opt.cmd) - .args(opt.args) - .stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .kill_on_drop(true) - .spawn()?, - ) - } + #[cfg(windows)] + return Ok( + Command::new("cmd") + .stdin(opt.stdio()) + .stdout(opt.stdio()) + .stderr(opt.stdio()) + .arg("/C") + .arg(opt.cmd) + .args(opt.args) + .kill_on_drop(true) + .spawn()?, + ); } diff --git a/core/src/tasks/workers/process.rs b/core/src/tasks/workers/process.rs index 6bed7b44..b45c86f7 100644 --- a/core/src/tasks/workers/process.rs +++ b/core/src/tasks/workers/process.rs @@ -2,7 +2,6 @@ use std::{ffi::OsString, mem}; use anyhow::Result; use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}}; -use tracing::trace; 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))?) } pub(crate) async fn open(&self, mut task: ProcessOpOpen) -> Result<()> { + let opt = ShellOpt::from(&mut task); if task.block { let _guard = BLOCKER.acquire().await.unwrap(); emit!(Stop(true)).await; - match external::shell(ShellOpt::from(&mut task)) { + match external::shell(opt) { Ok(mut child) => { child.wait().await.ok(); + self.done(task.id)?; } 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))?; - return self.done(task.id); + if task.orphan { + 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))?; - 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 stderr = BufReader::new(child.stderr.take().unwrap()).lines();