1909e4d10SGnoCiYeH use std::fs::{self, File}; 2909e4d10SGnoCiYeH use std::io::Read; 3909e4d10SGnoCiYeH use std::os::fd::FromRawFd; 4909e4d10SGnoCiYeH use std::sync::{Arc, Mutex}; 5dfd3fd98S裕依2439 6dfd3fd98S裕依2439 use lazy_static::lazy_static; 7909e4d10SGnoCiYeH 8909e4d10SGnoCiYeH use crate::error::ErrorFormat; 9909e4d10SGnoCiYeH use crate::manager::ctl_manager::CtlManager; 10909e4d10SGnoCiYeH 11909e4d10SGnoCiYeH use super::ctl_parser::{CommandOperation, CtlParser, Pattern}; 12909e4d10SGnoCiYeH use super::{ctl_path, DRAGON_REACH_CTL_PIPE}; 13909e4d10SGnoCiYeH 14909e4d10SGnoCiYeH lazy_static! { 15909e4d10SGnoCiYeH static ref CTL_READER: Mutex<Arc<File>> = { 16909e4d10SGnoCiYeH let file = Systemctl::init_listener(); 17909e4d10SGnoCiYeH Mutex::new(Arc::new(file)) 18909e4d10SGnoCiYeH }; 19909e4d10SGnoCiYeH } 20909e4d10SGnoCiYeH 21909e4d10SGnoCiYeH pub struct Command { 22909e4d10SGnoCiYeH pub(crate) operation: CommandOperation, 23909e4d10SGnoCiYeH pub(crate) args: Option<Vec<String>>, 24909e4d10SGnoCiYeH pub(crate) patterns: Vec<Pattern>, 25909e4d10SGnoCiYeH } 26909e4d10SGnoCiYeH 27909e4d10SGnoCiYeH impl Command { 28909e4d10SGnoCiYeH #[allow(dead_code)] new(op: CommandOperation, patterns: Vec<Pattern>, args: Option<Vec<String>>) -> Self29909e4d10SGnoCiYeH fn new(op: CommandOperation, patterns: Vec<Pattern>, args: Option<Vec<String>>) -> Self { 30909e4d10SGnoCiYeH Command { 31909e4d10SGnoCiYeH operation: op, 32909e4d10SGnoCiYeH args, 33909e4d10SGnoCiYeH patterns: patterns, 34909e4d10SGnoCiYeH } 35909e4d10SGnoCiYeH } 36909e4d10SGnoCiYeH } 37909e4d10SGnoCiYeH 38909e4d10SGnoCiYeH impl Default for Command { default() -> Self39909e4d10SGnoCiYeH fn default() -> Self { 40909e4d10SGnoCiYeH Command { 41909e4d10SGnoCiYeH operation: CommandOperation::None, 42909e4d10SGnoCiYeH args: None, 43909e4d10SGnoCiYeH patterns: Vec::new(), 44909e4d10SGnoCiYeH } 45909e4d10SGnoCiYeH } 46909e4d10SGnoCiYeH } 47909e4d10SGnoCiYeH 48909e4d10SGnoCiYeH pub struct Systemctl; 49909e4d10SGnoCiYeH 50909e4d10SGnoCiYeH impl Systemctl { 51*2069cc0dSBrahmaMantra /// # 初始化系统服务控制 - 初始化系统服务控制管道 init()52909e4d10SGnoCiYeH pub fn init() { 53909e4d10SGnoCiYeH Self::init_ctl_pipe(); 54909e4d10SGnoCiYeH } 55*2069cc0dSBrahmaMantra /// # 初始化监听器 - 初始化系统服务控制命令监听器 56*2069cc0dSBrahmaMantra /// 57*2069cc0dSBrahmaMantra /// 打开系统服务控制命令的管道文件描述符,并设置为非阻塞模式。 58*2069cc0dSBrahmaMantra /// init_listener() -> File59909e4d10SGnoCiYeH pub fn init_listener() -> File { 60909e4d10SGnoCiYeH let fd = unsafe { libc::open(ctl_path().as_ptr(), libc::O_RDONLY | libc::O_NONBLOCK) }; 61909e4d10SGnoCiYeH if fd < 0 { 62909e4d10SGnoCiYeH panic!("open ctl pipe error"); 63909e4d10SGnoCiYeH } 64909e4d10SGnoCiYeH unsafe { File::from_raw_fd(fd) } 65909e4d10SGnoCiYeH } 66*2069cc0dSBrahmaMantra /// # 监听控制命令 - 监听系统服务控制命令 67*2069cc0dSBrahmaMantra /// 68*2069cc0dSBrahmaMantra /// 持续从系统服务控制管道中读取命令。 69*2069cc0dSBrahmaMantra /// ctl_listen()70909e4d10SGnoCiYeH pub fn ctl_listen() { 71909e4d10SGnoCiYeH let mut guard = CTL_READER.lock().unwrap(); 72909e4d10SGnoCiYeH let mut s = String::new(); 73909e4d10SGnoCiYeH if let Ok(size) = guard.read_to_string(&mut s) { 74909e4d10SGnoCiYeH if size == 0 { 75909e4d10SGnoCiYeH return; 76909e4d10SGnoCiYeH } 77909e4d10SGnoCiYeH match CtlParser::parse_ctl(&s) { 78909e4d10SGnoCiYeH Ok(cmd) => { 79909e4d10SGnoCiYeH let _ = CtlManager::exec_ctl(cmd); 80909e4d10SGnoCiYeH } 81909e4d10SGnoCiYeH Err(err) => { 82909e4d10SGnoCiYeH eprintln!("parse tcl command error: {}", err.error_format()); 83909e4d10SGnoCiYeH } 84909e4d10SGnoCiYeH } 85909e4d10SGnoCiYeH } 86909e4d10SGnoCiYeH } 87909e4d10SGnoCiYeH 88*2069cc0dSBrahmaMantra /// # 检查控制管道是否存在 - 检查系统服务控制管道文件是否存在 89*2069cc0dSBrahmaMantra /// 90*2069cc0dSBrahmaMantra /// 返回管道文件是否存在。 91*2069cc0dSBrahmaMantra /// is_ctl_exists() -> bool92909e4d10SGnoCiYeH fn is_ctl_exists() -> bool { 93909e4d10SGnoCiYeH if let Ok(metadata) = fs::metadata(DRAGON_REACH_CTL_PIPE) { 94909e4d10SGnoCiYeH metadata.is_file() 95909e4d10SGnoCiYeH } else { 96909e4d10SGnoCiYeH false 97909e4d10SGnoCiYeH } 98909e4d10SGnoCiYeH } 99909e4d10SGnoCiYeH init_ctl_pipe()100909e4d10SGnoCiYeH fn init_ctl_pipe() { 101909e4d10SGnoCiYeH if !Self::is_ctl_exists() { 102909e4d10SGnoCiYeH let path = ctl_path(); 103909e4d10SGnoCiYeH let ret = unsafe { libc::mkfifo(path.as_ptr(), 0o666) }; 104909e4d10SGnoCiYeH if ret != 0 { 105909e4d10SGnoCiYeH // 创建管道失败打日志 1067c7ad4f0SLoGin panic!("create ctl pipe failed, err: {ret}"); 107909e4d10SGnoCiYeH } 108909e4d10SGnoCiYeH } 109909e4d10SGnoCiYeH } 110909e4d10SGnoCiYeH } 111