1 #[cfg(target_os = "dragonos")] 2 use drstd as std; 3 4 use std::{eprint, eprintln, print, process::Command, string::String, vec::Vec}; 5 6 use crate::{ 7 error::runtime_error::{RuntimeError, RuntimeErrorType}, 8 manager::UnitManager, 9 }; 10 11 #[derive(Debug, Clone, Default)] 12 pub struct CmdTask { 13 pub path: String, 14 pub cmd: Vec<String>, 15 pub ignore: bool, //表示忽略这个命令的错误,即使它运行失败也不影响unit正常运作 16 pub dir: String, 17 pub envs: Vec<(String, String)>, 18 pub pid: u32, 19 } 20 21 impl CmdTask { 22 /// ## 以新建进程的方式运行这个cmd 23 pub fn spawn(&self) -> Result<(), RuntimeError> { 24 let result = Command::new(&self.path) 25 .args(&self.cmd) 26 .current_dir(self.dir.clone()) 27 .envs(self.envs.clone()) 28 .spawn(); 29 match result { 30 Ok(proc) => { 31 UnitManager::push_cmd_proc(proc); 32 } 33 Err(err) => { 34 if !self.ignore { 35 eprintln!("{}: Command failed: {}", self.path, err); 36 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 37 } 38 } 39 } 40 Ok(()) 41 } 42 43 /// ## 阻塞式运行 44 pub fn no_spawn(&self) -> Result<(), RuntimeError> { 45 let result = Command::new(&self.path) 46 .args(&self.cmd) 47 .current_dir(self.dir.clone()) 48 .envs(self.envs.clone()) 49 .output(); 50 match result { 51 Ok(output) => { 52 print!("{}", String::from_utf8_lossy(&output.stdout)); 53 eprint!("{}", String::from_utf8_lossy(&output.stderr)); 54 if !output.status.success() { 55 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 56 } 57 } 58 Err(err) => { 59 if !self.ignore { 60 eprintln!("{}: Command failed: {}", self.path, err); 61 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 62 } 63 } 64 } 65 Ok(()) 66 } 67 68 /// ## 若这个cmd任务spawn了,则kill这个cmd进程 69 pub fn stop(&mut self) { 70 if self.pid != 0 { 71 let res = UnitManager::pop_cmd_proc(self.pid).unwrap(); 72 73 let mut proc = res.lock().unwrap(); 74 75 match proc.try_wait() { 76 //进程正常退出 77 Ok(Some(_status)) => {} 78 //进程错误退出(或启动失败) 79 _ => { 80 proc.kill().expect("Cannot kill cmd task"); 81 } 82 }; 83 } 84 } 85 } 86