瀏覽代碼

完成Service的解析,重构代码结构,优化解析错误处理

GnoCiYeH 1 年之前
父節點
當前提交
0f95f78df5

+ 3 - 1
.gitignore

@@ -1,2 +1,4 @@
 /target
-Cargo.lock
+Cargo.lock
+/DragonReach
+/.vscode

+ 0 - 7
.vscode/launch.json

@@ -1,7 +0,0 @@
-{
-    // 使用 IntelliSense 了解相关属性。 
-    // 悬停以查看现有属性的描述。
-    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
-    "version": "0.2.0",
-    "configurations": []
-}

+ 8 - 3
Cargo.toml

@@ -10,10 +10,15 @@ path = "src/main.rs"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-#drstd = {git = "https://git.mirrors.dragonos.org/DragonOS-Community/drstd.git", revision = "a4d693c682"}
-#lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
-lazy_static = {version = "1.4.0"}
 hashbrown = "0.11"
+cfg-if = { version = "1.0"}
+
+[target.'cfg(target_os = "dragonos")'.dependencies]
+drstd = {git = "https://git.mirrors.dragonos.org/DragonOS-Community/drstd.git", revision = "a4d693c682"}
+lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
+
+[target.'cfg(not(target_os = "dragonos"))'.dependencies]
+lazy_static = {version = "1.4.0"}
 
 [profile.release]
 panic = 'abort'

+ 16 - 4
parse_test/test.service

@@ -1,8 +1,20 @@
 [Unit]
-Description=test
+Description=My Service
+Documentation=https://example.com/docs/my-service.html
+#After=network.target
 
 [Service]
-ExecStart=/path/to/my-service run docker /path/to/my-service run / make
-Restart=always
+Type=simple
+ExecStart=/home/heyicong/DragonOs/bin/sysroot/bin/DragonReach --option1=value1 --option2=value2
+WorkingDirectory=/home/heyicong/
+User=myuser
+Group=mygroup
+Environment=VAR1=value1
+Environment=VAR2=value2
+Restart=on-failure
+RestartSec=5s
+TimeoutStartSec=10s
+TimeoutStopSec=10s
 
-[Install]
+[Install]
+#WantedBy=multi-user.target

+ 29 - 1
src/error/mod.rs

@@ -1,7 +1,13 @@
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+use std::format;
+use std::string::String;
+use std::string::ToString;
+/// 解析错误,错误信息应该包括文件名以及行号
 #[repr(i32)]
 #[derive(Debug, PartialEq, Eq, Clone)]
 #[allow(dead_code, non_camel_case_types)]
-pub enum ParseError {
+pub enum ParseErrorType {
     /// 不合法参数
     EINVAL,
     /// 结果过大 Result too large.
@@ -19,3 +25,25 @@ pub enum ParseError {
     /// 不是目录
     ENODIR,
 }
+
+/// 错误信息应该包括错误类型ParseErrorType,当前解析的文件名,当前解析的行号
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct ParseError(ParseErrorType,String,usize);
+
+impl ParseError {
+    pub fn new(error_type: ParseErrorType,file_name: String,line_number: usize) -> ParseError {
+        ParseError(error_type,file_name,line_number)
+    }
+
+    pub fn set_file(&mut self,path: &str) {
+        self.1 = path.to_string();
+    }
+
+    pub fn set_linenum(&mut self,linenum: usize) {
+        self.2 = linenum;
+    }
+
+    pub fn error_format(&self) -> String {
+        format!("Parse Error!,Error Type: {:?}, File: {}, Line: {}",self.0,self.1,self.2)
+    }
+}

+ 67 - 16
src/main.rs

@@ -1,14 +1,19 @@
-// #![no_std]
-// #![no_main]
+#![no_std]
+#![no_main]
+use cfg_if::cfg_if;
 
-//extern crate drstd;
-extern crate hashbrown;
+cfg_if!{
+    if #[cfg(target_os = "dragonos")]{
+        extern crate drstd;
+        use drstd as std;
+        use std::print;
+        use std::println;
+        use std::rc::Rc;
+        use unit::service::ServiceUnit;
+    }
+}
 
-//use drstd as std;
-use std::print;
-use std::println;
-use std::rc::Rc;
-use unit::service::ServiceUnit;
+extern crate hashbrown;
 
 mod contants;
 mod error;
@@ -22,13 +27,59 @@ use self::unit::Unit;
 
 pub struct FileDescriptor(usize);
 
-//#[no_mangle]
+#[cfg(target_os = "dragonos")]
+#[no_mangle]
 fn main() {
-    let service =
-        ServiceUnit::from_path("/home/heyicong/DragonReach/parse_test/test.service").unwrap();
+    use unit::service::ServiceUnit;
+
+    let service = match ServiceUnit::from_path("/bin/test.service"){
+        Ok(service) => service,
+        Err(e) => {
+            println!("Error:{}",e.error_format());
+            return;
+        }
+    };
     let service = service.as_ref();
-    let cmds = &service.service_part.exec_start;
-    for cmd in cmds{
-        println!("{},{}",cmd.path,cmd.cmd);
-    }
+    println!("parse_result:");
+    println!("Description:{:?}", service.unit_base().unit_part().description());
+    println!("Documentation:{:?}",service.unit_base().unit_part().documentation());
+    println!("ServiceType:{:?}",service.service_part().service_type());
+    println!("ExecStrat:{:?}",service.service_part().exec_start());
+    println!("WorkingDirectory:{:?}",service.service_part().working_directory());
+    println!("Environment:{:?}",service.service_part().environment());
+    println!("Restart:{:?}",service.service_part().restart());
+    println!("RestartSec:{:?}",service.service_part().restart_sec());
+    println!("User:{:?}",service.service_part().user());
+    println!("Group:{:?}",service.service_part().group());
+    println!("TimeoutStartSec:{:?}",service.service_part().timeout_start_sec());
+    println!("TimeoutStopSec:{:?}",service.service_part().timeout_stop_sec());
+}
+
+#[cfg(not(target_os = "dragonos"))]
+fn main() {
+    use unit::service::ServiceUnit;
+
+    let service = match ServiceUnit::from_path("/home/heyicong/DragonReach/parse_test/test.service"){
+        Ok(service) => service,
+        Err(e) => {
+            println!("Error:{}",e.error_format());
+            return;
+        }
+    };
+
+    
+    let service = service.as_ref();
+    println!("parse_result:");
+    println!("Description:{:?}", service.unit_base().unit_part().description());
+    println!("Documentation:{:?}",service.unit_base().unit_part().documentation());
+    println!("ServiceType:{:?}",service.service_part().service_type());
+    println!("ExecStrat:{:?}",service.service_part().exec_start());
+    println!("WorkingDirectory:{:?}",service.service_part().working_directory());
+    println!("Environment:{:?}",service.service_part().environment());
+    println!("Restart:{:?}",service.service_part().restart());
+    println!("RestartSec:{:?}",service.service_part().restart_sec());
+    println!("User:{:?}",service.service_part().user());
+    println!("Group:{:?}",service.service_part().group());
+    println!("TimeoutStartSec:{:?}",service.service_part().timeout_start_sec());
+    println!("TimeoutStopSec:{:?}",service.service_part().timeout_stop_sec());
 }

+ 69 - 60
src/parse/mod.rs

@@ -1,29 +1,27 @@
+use crate::error::ParseErrorType;
 use crate::unit::{BaseUnit, Unit};
 use crate::{
     error::ParseError,
     unit::{service::ServiceUnitAttr, BaseUnitAttr, InstallUnitAttr, UnitType},
 };
-use core::cell::RefCell;
-//use drstd as std;
+
+
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
 use hashbrown::HashMap;
 use lazy_static::lazy_static;
-use std::boxed::Box;
 use std::format;
 use std::fs::File;
 use std::io::{self, BufRead};
 use std::rc::Rc;
 use std::string::String;
 use std::vec::Vec;
+use std::string::ToString;
 
-use self::parse_base_unit::BaseUnitParser;
-
-pub mod parse_base_unit;
+pub mod parse_target;
 pub mod parse_service;
-mod parse_util;
-
-pub trait AttrParse<T> {
-    fn parse_and_set_attribute(unit: &mut T, attr: &str, val: &str) -> Result<(), ParseError>;
-}
+pub mod parse_util;
 
 //对应Unit段类型
 #[derive(PartialEq, Clone, Copy)]
@@ -35,7 +33,7 @@ pub enum Segment {
 }
 
 lazy_static! {
-    static ref UNIT_SUFFIX: HashMap<&'static str, UnitType> = {
+    pub static ref UNIT_SUFFIX: HashMap<&'static str, UnitType> = {
         let mut table = HashMap::new();
         table.insert("automount", UnitType::Automount);
         table.insert("device", UnitType::Device);
@@ -51,14 +49,14 @@ lazy_static! {
         table.insert("timer", UnitType::Timer);
         table
     };
-    static ref SEGMENT_TABLE: HashMap<&'static str, Segment> = {
+    pub static ref SEGMENT_TABLE: HashMap<&'static str, Segment> = {
         let mut table = HashMap::new();
         table.insert("[Unit]", Segment::Unit);
         table.insert("[Install]", Segment::Install);
         table.insert("[Service]", Segment::Service);
         table
     };
-    static ref INSTALL_UNIT_ATTR_TABLE: HashMap<&'static str, InstallUnitAttr> = {
+    pub static ref INSTALL_UNIT_ATTR_TABLE: HashMap<&'static str, InstallUnitAttr> = {
         let mut unit_attr_table = HashMap::new();
         unit_attr_table.insert("WantedBy", InstallUnitAttr::WantedBy);
         unit_attr_table.insert("RequiredBy", InstallUnitAttr::RequiredBy);
@@ -66,7 +64,7 @@ lazy_static! {
         unit_attr_table.insert("Alias", InstallUnitAttr::Alias);
         unit_attr_table
     };
-    static ref SERVICE_UNIT_ATTR_TABLE: HashMap<&'static str, ServiceUnitAttr> = {
+    pub static ref SERVICE_UNIT_ATTR_TABLE: HashMap<&'static str, ServiceUnitAttr> = {
         let mut unit_attr_table = HashMap::new();
         unit_attr_table.insert("Type", ServiceUnitAttr::Type);
         unit_attr_table.insert("RemainAfterExit", ServiceUnitAttr::RemainAfterExit);
@@ -90,7 +88,7 @@ lazy_static! {
         unit_attr_table.insert("MountFlags", ServiceUnitAttr::MountFlags);
         unit_attr_table
     };
-    static ref BASE_UNIT_ATTR_TABLE: HashMap<&'static str, BaseUnitAttr> = {
+    pub static ref BASE_UNIT_ATTR_TABLE: HashMap<&'static str, BaseUnitAttr> = {
         let mut unit_attr_table = HashMap::new();
         unit_attr_table.insert("Description", BaseUnitAttr::Description);
         unit_attr_table.insert("Documentation", BaseUnitAttr::Documentation);
@@ -104,7 +102,7 @@ lazy_static! {
         unit_attr_table.insert("Conflicts", BaseUnitAttr::Conflicts);
         unit_attr_table
     };
-    static ref BASE_IEC: HashMap<&'static str, u64> = {
+    pub static ref BASE_IEC: HashMap<&'static str, u64> = {
         let mut table = HashMap::new();
         table.insert(
             "E",
@@ -119,7 +117,7 @@ lazy_static! {
         table.insert("", 1u64);
         table
     };
-    static ref BASE_SI: HashMap<&'static str, u64> = {
+    pub static ref BASE_SI: HashMap<&'static str, u64> = {
         let mut table = HashMap::new();
         table.insert(
             "E",
@@ -134,7 +132,7 @@ lazy_static! {
         table.insert("", 1u64);
         table
     };
-    static ref SEC_UNIT_TABLE: HashMap<&'static str, u64> = {
+    pub static ref SEC_UNIT_TABLE: HashMap<&'static str, u64> = {
         let mut table = HashMap::new();
         table.insert("h", 60 * 60 * 1000 * 1000 * 1000);
         table.insert("min", 60 * 1000 * 1000 * 1000);
@@ -157,7 +155,7 @@ impl UnitParser {
     /// 从path获取到BufReader,此方法将会检验文件类型
     ///
     /// @param path 需解析的文件路径
-    /// 
+    ///
     /// @param unit_type 指定Unit类型
     ///
     /// @return 成功则返回对应BufReader,否则返回Err
@@ -165,21 +163,21 @@ impl UnitParser {
         let suffix = match path.rfind('.') {
             Some(idx) => &path[idx + 1..],
             None => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
             }
         };
         let u_type = UNIT_SUFFIX.get(suffix);
         if u_type.is_none() {
-            return Err(ParseError::EFILE);
+            return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
         }
         if *(u_type.unwrap()) != unit_type {
-            return Err(ParseError::EFILE);
+            return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
         }
 
         let file = match File::open(path) {
             Ok(file) => file,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(),0));
             }
         };
         return Ok(io::BufReader::new(file));
@@ -188,24 +186,18 @@ impl UnitParser {
     /// @brief 将path路径的文件解析为unit_type类型的Unit
     ///
     /// 该方法解析每个Unit共有的段(Unit,Install),其余独有的段属性将会交付T类型的Unit去解析
-    /// TODO:该方法多态性做得不是很优雅,后期可以重构一下
     ///
     /// @param path 需解析的文件路径
-    /// 
+    ///
     /// @param unit_type 指定Unit类型
-    /// 
-    /// @param unit 需要的unit对象,解析结果会放置在里面,将会调用unit的set_attr方法设置独有属性
-    /// 
-    /// @param unit_base 共有段的解析结果将会放置在unit_base中
     ///
-    /// @return 解析成功则返回Ok(()),否则返回Err
-    pub fn parse<T: Unit>(
-        path: &str,
-        unit_type: UnitType,
-        unit: &mut T,
-        unit_base: &mut BaseUnit,
-    ) -> Result<(), ParseError> {
-        unit_base.unit_type = unit_type;
+    /// @return 解析成功则返回Ok(Rc<T>),否则返回Err
+    pub fn parse<T: Unit + Default>(path: &str, unit_type: UnitType) -> Result<Rc<T>, ParseError> {
+        let mut unit: T = T::default();
+        let mut unit_base = BaseUnit::default();
+        //设置unit类型标记
+        unit_base.set_unit_type(unit_type);
+
         let reader = UnitParser::get_unit_reader(path, unit_type)?;
 
         //用于记录当前段的类型
@@ -241,7 +233,7 @@ impl UnitParser {
             }
             if segment == Segment::None {
                 //未找到段名则不能继续匹配
-                return Err(ParseError::ESyntaxError);
+                return Err(ParseError::new(ParseErrorType::ESyntaxError, path.to_string(),i + 1));
             }
 
             //下面进行属性匹配
@@ -260,35 +252,52 @@ impl UnitParser {
                 break;
             }
             //=号分割后第一个元素为属性,后面的均为值,若一行出现两个等号则是语法错误
-            let attr_val_map = line.split('=').collect::<Vec<&str>>();
-            if attr_val_map.len() != 2 {
-                return Err(ParseError::ESyntaxError);
-            }
-
+            let (attr_str,val_str) = match line.find('=') {
+                Some(idx) => {
+                    (line[..idx].trim(), line[idx+1..].trim())
+                }
+                None => {
+                    return Err(ParseError::new(ParseErrorType::ESyntaxError, path.to_string(),i + 1));
+                }
+            };
             //首先匹配所有unit文件都有的unit段和install段
-            if BASE_UNIT_ATTR_TABLE.get(attr_val_map[0]).is_some() {
+            if BASE_UNIT_ATTR_TABLE.get(attr_str).is_some() {
                 if segment != Segment::Unit {
-                    return Err(ParseError::EINVAL);
+                    return Err(ParseError::new(ParseErrorType::EINVAL, path.to_string(),i + 1));
+                }
+                if let Err(e) = unit_base.set_unit_part_attr(
+                    BASE_UNIT_ATTR_TABLE.get(attr_str).unwrap(),
+                    val_str,
+                ){
+                    let mut e = e.clone();
+                    e.set_file(path);
+                    e.set_linenum(i + 1);
+                    return Err(e);
                 }
-                BaseUnitParser::parse_and_set_base_unit_attribute(
-                    &mut unit_base.unit_part,
-                    BASE_UNIT_ATTR_TABLE.get(attr_val_map[0]).unwrap(),
-                    attr_val_map[1],
-                )?
-            } else if INSTALL_UNIT_ATTR_TABLE.get(attr_val_map[0]).is_some() {
+            } else if INSTALL_UNIT_ATTR_TABLE.get(attr_str).is_some() {
                 if segment != Segment::Install {
-                    return Err(ParseError::EINVAL);
+                    return Err(ParseError::new(ParseErrorType::EINVAL, path.to_string(),i + 1));
+                }
+                if let Err(e) = unit_base.set_install_part_attr(
+                    INSTALL_UNIT_ATTR_TABLE.get(attr_str).unwrap(),
+                    val_str,
+                ){
+                    let mut e = e.clone();
+                    e.set_file(path);
+                    e.set_linenum(i + 1);
+                    return Err(e);
                 }
-                BaseUnitParser::parse_and_set_base_install_attribute(
-                    &mut unit_base.install_part,
-                    INSTALL_UNIT_ATTR_TABLE.get(attr_val_map[0]).unwrap(),
-                    attr_val_map[1],
-                )?
             } else {
-                unit.set_attr(segment, attr_val_map[0], attr_val_map[1])?;
+                if let Err(e) = unit.set_attr(segment, attr_str, val_str){
+                    let mut e = e.clone();
+                    e.set_file(path);
+                    e.set_linenum(i + 1);
+                    return Err(e);
+                }
             }
             i += 1;
         }
-        return Ok(());
+        unit.set_unit_base(unit_base);
+        return Ok(Rc::new(unit));
     }
 }

+ 0 - 165
src/parse/parse_base_unit/mod.rs

@@ -1,165 +0,0 @@
-use crate::{
-    error::ParseError,
-    unit::{target::TargetUnit, BaseUnitAttr, InstallPart, UnitPart},
-};
-//use drstd as std;
-use std::rc::Rc;
-use std::string::String;
-use std::vec::Vec;
-
-use super::{parse_util::UnitParseUtil, InstallUnitAttr};
-
-//Unit同有部分的解析器
-pub struct BaseUnitParser;
-
-impl BaseUnitParser {
-    /// @brief 为Unit解析Unit段属性并添加
-    ///
-    /// 为Unit解析Unit段属性并添加
-    ///
-    /// @param unit_part UnitPart(Unit段结构体),解析结果将存在该结构体
-    /// 
-    /// @param attr BaseUnitAttr,Unit段的属性抽象
-    /// 
-    /// @param val 属性值
-    ///
-    /// @return 成功则返回Ok(()),否则返回Err
-    pub fn parse_and_set_base_unit_attribute(
-        unit_part: &mut UnitPart,
-        attr: &BaseUnitAttr,
-        val: &str,
-    ) -> Result<(), ParseError> {
-        match attr {
-            BaseUnitAttr::None => {
-                return Err(ParseError::ESyntaxError);
-            }
-            BaseUnitAttr::Description => unit_part.description = String::from(val),
-            BaseUnitAttr::Documentation => unit_part
-                .documentation
-                .extend(UnitParseUtil::parse_url(val)?),
-            BaseUnitAttr::Requires => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .requires
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::Wants => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .wants
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::After => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .after
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::Before => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .before
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::BindsTo => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .binds_to
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::PartOf => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .part_of
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::OnFailure => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    unit_part
-                        .on_failure
-                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
-                }
-            }
-            BaseUnitAttr::Conflicts => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
-                    unit_part.conflicts.push(unit);
-                }
-            }
-        }
-        return Ok(());
-    }
-
-    /// @brief 为Unit解析Install段属性并添加
-    ///
-    /// 为Unit解析Install段属性并添加
-    ///
-    /// @param install_part InstallPart(Install段结构体),解析结果将存在该结构体
-    /// 
-    /// @param attr BaseUnitAttr,Unit段的属性抽象
-    /// 
-    /// @param val 属性值
-    ///
-    /// @return 成功则返回Ok(()),否则返回Err
-    pub fn parse_and_set_base_install_attribute(
-        install_part: &mut InstallPart,
-        attr: &InstallUnitAttr,
-        val: &str,
-    ) -> Result<(), ParseError> {
-        match attr {
-            InstallUnitAttr::RequiredBy => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
-                    install_part.requires_by.push(unit);
-                }
-            }
-            InstallUnitAttr::Also => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
-                    install_part.also.push(unit);
-                }
-            }
-            InstallUnitAttr::WantedBy => {
-                let units = val.split_whitespace().collect::<Vec<&str>>();
-                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
-                for unit_path in units {
-                    let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
-                    install_part.wanted_by.push(unit);
-                }
-            }
-            InstallUnitAttr::Alias => {
-                install_part.alias = String::from(val);
-            }
-            InstallUnitAttr::None => {
-                return Err(ParseError::EINVAL);
-            }
-        }
-        return Ok(());
-    }
-}

+ 7 - 162
src/parse/parse_service/mod.rs

@@ -1,15 +1,11 @@
-use super::{AttrParse, ServiceUnitAttr, UnitParser, SERVICE_UNIT_ATTR_TABLE};
+use super::UnitParser;
 use crate::error::ParseError;
-use crate::parse::parse_util::UnitParseUtil;
-use crate::unit::service::{MountFlag, RestartOption, ServiceType, ServiceUnit};
-use crate::unit::{BaseUnit, Unit};
-use core::borrow::BorrowMut;
-use core::cell::RefCell;
-//use drstd as std;
-use std::boxed::Box;
-use std::fs;
+use crate::unit::service::ServiceUnit;
+
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
 use std::rc::Rc;
-use std::string::String;
 pub struct ServiceParser;
 
 impl ServiceParser {
@@ -21,159 +17,8 @@ impl ServiceParser {
     ///
     /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
     pub fn parse(path: &str) -> Result<Rc<ServiceUnit>, ParseError> {
-        let mut service = ServiceUnit::default();
-        let mut unit_base = BaseUnit::default();
-
         //交付总解析器
-        UnitParser::parse::<ServiceUnit>(
-            path,
-            crate::unit::UnitType::Service,
-            &mut service,
-            &mut unit_base,
-        )?;
-
-        //设置
-        service.unit_base = unit_base;
-        let mut service = Rc::new(service);
+        let service = UnitParser::parse::<ServiceUnit>(path, crate::unit::UnitType::Service)?;
         return Ok(service);
     }
 }
-
-impl AttrParse<ServiceUnit> for ServiceParser {
-    /// @brief 为Service类型Unit解析并添加属性
-    ///
-    /// 为Service类型Unit解析并添加属性
-    ///
-    /// @param service ServiceUnit对象
-    /// 
-    /// @param attr_str 属性名
-    /// 
-    /// @param val 属性值
-    ///
-    /// @return 成功则返回Ok(()),否则返回Err
-    fn parse_and_set_attribute(
-        service: &mut ServiceUnit,
-        attr_str: &str,
-        val: &str,
-    ) -> Result<(), ParseError> {
-        //let mut service = *unit;
-
-        let attr = match SERVICE_UNIT_ATTR_TABLE.get(attr_str) {
-            Some(val) => val,
-            None => {
-                return Err(ParseError::EINVAL);
-            }
-        };
-        match attr {
-            ServiceUnitAttr::Type => match val {
-                "simple" => service.service_part.service_type = ServiceType::Simple,
-                "forking" => service.service_part.service_type = ServiceType::Forking,
-                "oneshot" => service.service_part.service_type = ServiceType::OneShot,
-                "dbus" => service.service_part.service_type = ServiceType::Dbus,
-                "notify" => service.service_part.service_type = ServiceType::Notify,
-                "idle" => service.service_part.service_type = ServiceType::Idle,
-                _ => {
-                    return Err(ParseError::EINVAL);
-                }
-            },
-            ServiceUnitAttr::RemainAfterExit => {
-                service.service_part.remain_after_exit = UnitParseUtil::parse_boolean(val)?
-            }
-            ServiceUnitAttr::ExecStart => {
-                service
-                    .service_part
-                    .exec_start
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::ExecStartPre => {
-                service
-                    .service_part
-                    .exec_start_pre
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::ExecStartPos => {
-                service
-                    .service_part
-                    .exec_start_pos
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::ExecReload => {
-                service
-                    .service_part
-                    .exec_reload
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::ExecStopPost => {
-                service
-                    .service_part
-                    .exec_stop_post
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::ExecStop => {
-                service
-                    .service_part
-                    .exec_stop
-                    .extend(UnitParseUtil::parse_cmd_task(val)?);
-            }
-            ServiceUnitAttr::RestartSec => {
-                service.service_part.restart_sec = UnitParseUtil::parse_sec(val)?
-            }
-            ServiceUnitAttr::Restart => match val {
-                "always" => service.service_part.restart = RestartOption::AlwaysRestart,
-                "on-success" => service.service_part.restart = RestartOption::OnSuccess,
-                "on-failure" => service.service_part.restart = RestartOption::OnFailure,
-                "on-abnormal" => service.service_part.restart = RestartOption::OnAbnormal,
-                "on-abort" => service.service_part.restart = RestartOption::OnAbort,
-                "on-watchdog" => service.service_part.restart = RestartOption::OnWatchdog,
-                _ => {
-                    return Err(ParseError::EINVAL);
-                }
-            },
-            ServiceUnitAttr::TimeoutStartSec => {
-                service.service_part.timeout_start_sec = UnitParseUtil::parse_sec(val)?
-            }
-            ServiceUnitAttr::TimeoutStopSec => {
-                service.service_part.timeout_stop_sec = UnitParseUtil::parse_sec(val)?
-            }
-            ServiceUnitAttr::Environment => {
-                service.service_part.environment = String::from(val);
-            }
-            ServiceUnitAttr::EnvironmentFile => {
-                if !UnitParseUtil::is_absolute_path(val) {
-                    return Err(ParseError::EFILE);
-                }
-                service.service_part.environment_file = String::from(val);
-            }
-            ServiceUnitAttr::Nice => {
-                service.service_part.nice = UnitParseUtil::parse_nice(val)?;
-            }
-            ServiceUnitAttr::WorkingDirectory => {
-                if !UnitParseUtil::is_dir(val) {
-                    return Err(ParseError::ENODIR);
-                }
-                service.service_part.working_directory = String::from(val);
-            }
-            ServiceUnitAttr::User => {
-                //TODO: 检查系统是否存在这个用户
-                service.service_part.user = String::from(val);
-            }
-            ServiceUnitAttr::Group => {
-                //TODO: 检查系统是否存在该用户组
-                service.service_part.group = String::from(val);
-            }
-            ServiceUnitAttr::MountFlags => match val {
-                "shared" => service.service_part.mount_flags = MountFlag::Shared,
-                "slave" => service.service_part.mount_flags = MountFlag::Slave,
-                "private" => service.service_part.mount_flags = MountFlag::Private,
-                _ => {
-                    return Err(ParseError::EINVAL);
-                }
-            },
-            _ => {
-                return Err(ParseError::EINVAL);
-            }
-        }
-
-        return Ok(());
-    }
-}

+ 25 - 0
src/parse/parse_target/mod.rs

@@ -0,0 +1,25 @@
+use super::UnitParser;
+use crate::error::ParseError;
+use crate::unit::target::TargetUnit;
+
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+use std::rc::Rc;
+
+pub struct TargetParser;
+
+impl TargetParser {
+    /// @brief 解析Service类型Unit的
+    ///
+    /// 从path解析Service类型Unit
+    ///
+    /// @param path 需解析的文件路径
+    ///
+    /// @return 成功则返回Ok(Rc<ServiceUnit>),否则返回Err
+    pub fn parse(path: &str) -> Result<Rc<TargetUnit>, ParseError> {
+        //交付总解析器
+        let service = UnitParser::parse::<TargetUnit>(path, crate::unit::UnitType::Service)?;
+        return Ok(service);
+    }
+}

+ 127 - 49
src/parse/parse_util/mod.rs

@@ -1,14 +1,23 @@
 use crate::{
     contants::{AF_INET, AF_INET6, IPV4_MIN_MTU, IPV6_MIN_MTU, PRIO_MAX, PRIO_MIN},
-    error::ParseError,
+    error::{ParseError, ParseErrorType},
     task::cmdtask::CmdTask,
     unit::{Unit, Url},
     FileDescriptor,
 };
-//use drstd::std;
-use std::{format, fs, path::Path, rc::Rc, string::String, string::ToString, vec, vec::Vec};
 
-use super::{parse_service::ServiceParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE};
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
+use std::{
+    format, fs, path::Path, print, println, rc::Rc, string::String, string::ToString, vec, vec::Vec, os::unix::prelude::PermissionsExt,
+};
+
+use std::os::unix::fs::MetadataExt;
+
+use super::{
+    parse_service::ServiceParser, parse_target::TargetParser, BASE_IEC, BASE_SI, SEC_UNIT_TABLE,
+};
 
 #[derive(PartialEq)]
 pub enum SizeBase {
@@ -38,7 +47,7 @@ impl UnitParseUtil {
             return Ok(false);
         }
 
-        return Err(ParseError::EINVAL);
+        return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
     }
 
     /// @brief 解析pid
@@ -54,19 +63,19 @@ impl UnitParseUtil {
         let pid_ul = match s.parse::<u64>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
         let pid: i32 = pid_ul as i32;
 
         if (pid as u64) != pid_ul {
             //如果在从pid_t转换为u64之后与之前不等,则说明发生了截断,返回错误
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         if pid < 0 {
             //pid小于0不合法
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(pid);
@@ -84,13 +93,13 @@ impl UnitParseUtil {
         let m = match u32::from_str_radix(s, 8) {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         //如果模式大于权限的最大值则为非法权限,返回错误
         if m > 0o7777 {
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(m);
@@ -108,12 +117,12 @@ impl UnitParseUtil {
         let ret: i32 = match s.parse::<i32>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if ret <= 0 {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(ret);
@@ -134,13 +143,13 @@ impl UnitParseUtil {
             Ok(val) => val,
             Err(_) => {
                 //针对非法字符出错时
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         //针对数据溢出时的报错
         if mtu > u32::MAX as u64 {
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         let mtu: u32 = mtu as u32;
@@ -152,7 +161,7 @@ impl UnitParseUtil {
         } else if family == AF_INET {
             min_mtu = IPV4_MIN_MTU;
         } else {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(mtu);
@@ -184,7 +193,7 @@ impl UnitParseUtil {
                 let fraction = match fraction[1..].parse::<u64>() {
                     Ok(val) => val,
                     Err(_) => {
-                        return Err(ParseError::EINVAL);
+                        return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                     }
                 };
                 (integer, fraction)
@@ -198,14 +207,14 @@ impl UnitParseUtil {
             factor = match BASE_IEC.get(suffix) {
                 Some(val) => *val,
                 None => {
-                    return Err(ParseError::EINVAL);
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                 }
             }
         } else if base == SizeBase::Si {
             factor = match BASE_SI.get(suffix) {
                 Some(val) => *val,
                 None => {
-                    return Err(ParseError::EINVAL);
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                 }
             }
         }
@@ -226,17 +235,17 @@ impl UnitParseUtil {
         let size: u64 = match s.parse::<u64>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if size < 512 || size > 4096 {
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         //判断是否为2的幂,如果不是则报错
         if (size & (size - 1)) != 0 {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(size);
@@ -258,7 +267,7 @@ impl UnitParseUtil {
                 let ret = match s.parse::<u32>() {
                     Ok(val) => val,
                     Err(_) => {
-                        return Err(ParseError::EINVAL);
+                        return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
                     }
                 };
                 return Ok((ret, ret));
@@ -272,14 +281,14 @@ impl UnitParseUtil {
         let l = match l.parse::<u32>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
         let r = r.trim();
         let r = match r.parse::<u32>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
@@ -298,12 +307,12 @@ impl UnitParseUtil {
         let fd = match s.parse::<i32>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if fd < 0 {
-            return Err(ParseError::EBADF);
+            return Err(ParseError::new(ParseErrorType::EBADF, String::new(), 0));
         }
 
         return Ok(FileDescriptor(fd as usize));
@@ -321,12 +330,12 @@ impl UnitParseUtil {
         let nice = match s.parse::<i8>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if nice > PRIO_MAX || nice < PRIO_MIN {
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::ERANGE, String::new(), 0));
         }
 
         return Ok(nice);
@@ -344,12 +353,12 @@ impl UnitParseUtil {
         let port = match s.parse::<u16>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if port == 0 {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok(port);
@@ -368,7 +377,7 @@ impl UnitParseUtil {
         let l = l as u16;
         let h = h as u16;
         if l <= 0 || l >= 65535 || h <= 0 || h >= 65535 {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
         }
 
         return Ok((l, h));
@@ -385,12 +394,12 @@ impl UnitParseUtil {
         let len = match s.parse::<u32>() {
             Ok(val) => val,
             Err(_) => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 
         if len > 128 {
-            return Err(ParseError::ERANGE);
+            return Err(ParseError::new(ParseErrorType::ERANGE, String::new(), 0));
         }
 
         return Ok(len);
@@ -437,22 +446,24 @@ impl UnitParseUtil {
         let idx = match path.rfind('.') {
             Some(val) => val,
             None => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
         };
 
         if idx == path.len() - 1 {
             //处理非法文件xxxx. 类型
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
         }
 
         let suffix = &path[idx + 1..];
 
         //通过文件后缀分发给不同类型的Unit解析器解析
-        let unit = match suffix {
+        let unit: Rc<dyn Unit> = match suffix {
+            //TODO: 目前为递归,后续应考虑从DragonReach管理的Unit表中寻找是否有该Unit,并且通过记录消除递归
             "service" => ServiceParser::parse(path)?,
+            "target" => TargetParser::parse(path)?,
             _ => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EFILE, path.to_string(), 0));
             }
         };
 
@@ -489,8 +500,8 @@ impl UnitParseUtil {
             }
 
             //得到的非绝对路径则不符合语法要求,报错
-            if !UnitParseUtil::is_absolute_path(path) {
-                return Err(ParseError::EINVAL);
+            if !UnitParseUtil::is_valid_exec_path(path) {
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
 
             cmd_task.path = String::from(path);
@@ -498,7 +509,7 @@ impl UnitParseUtil {
             //i += 1,继续匹配下一个单词
             i += 1;
             let mut cmd_str = String::new();
-            while i < cmds.len() && !UnitParseUtil::is_absolute_path(cmds[i]) {
+            while i < cmds.len() && !UnitParseUtil::is_valid_exec_path(cmds[i]) {
                 //命令可能会有多个单词,将多个命令整理成一个
                 let cmd = cmds[i];
                 cmd_str = format!("{} {}", cmd_str, cmd);
@@ -511,14 +522,55 @@ impl UnitParseUtil {
         return Ok(tasks);
     }
 
-    /// @brief 判断是否为绝对路径
+    /// @brief 判断是否为绝对路径,以及指向是否为可执行文件或者sh脚本
     ///
+    /// 目前该方法仅判断是否为绝对路径
+    /// 
     /// @param path 路径
     ///
     /// @return 解析成功则返回true,否则返回false
-    pub fn is_absolute_path(path: &str) -> bool {
+    pub fn is_valid_exec_path(path: &str) -> bool {
+        if !path.starts_with("/"){
+            return false;
+        }
+        return true;
+
+        //TODO: 后续应判断该文件是否为合法文件
+        //let path = Path::new(path);
+        //return Self::is_executable_file(path) || Self::is_shell_script(path);
+    }
+
+    pub fn is_valid_file(path: &str) -> bool {
+        if !path.starts_with("/"){
+            return false;
+        }
+        
         let path = Path::new(path);
-        path.is_absolute()
+        if let Ok(matadata) = fs::metadata(path) {
+            return matadata.is_file();
+        }
+
+        return false;
+    }
+
+    fn is_executable_file(path: &Path) -> bool {
+        if let Ok(metadata) = fs::metadata(path) {
+            // 检查文件类型是否是普通文件并且具有可执行权限
+            if metadata.is_file(){
+                let permissions = metadata.permissions().mode();
+                return permissions & 0o111 != 0;
+            }
+        }
+        false
+    }
+
+    fn is_shell_script(path: &Path) -> bool {
+        if let Some(extension) = path.extension() {
+            if extension == "sh" {
+                return true;
+            }
+        }
+        false
     }
 
     /// @brief 将对应的str解析为us(微秒)
@@ -539,7 +591,9 @@ impl UnitParseUtil {
                 //解析整数部分
                 integer = match s[..idx].parse::<u64>() {
                     Ok(val) => val,
-                    Err(_) => return Err(ParseError::EINVAL),
+                    Err(_) => {
+                        return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0))
+                    }
                 };
                 //获得小数+单位的字符串
                 let frac_and_unit = &s[(idx + 1)..];
@@ -548,7 +602,13 @@ impl UnitParseUtil {
                         //匹配小数部分
                         frac = match frac_and_unit[..val].parse::<u64>() {
                             Ok(val) => val,
-                            Err(_) => return Err(ParseError::EINVAL),
+                            Err(_) => {
+                                return Err(ParseError::new(
+                                    ParseErrorType::EINVAL,
+                                    String::new(),
+                                    0,
+                                ))
+                            }
                         };
                         //单位部分
                         unit = &frac_and_unit[val..];
@@ -557,7 +617,13 @@ impl UnitParseUtil {
                         //没有单位的情况,直接匹配小数
                         frac = match frac_and_unit.parse::<u64>() {
                             Ok(val) => val,
-                            Err(_) => return Err(ParseError::EINVAL),
+                            Err(_) => {
+                                return Err(ParseError::new(
+                                    ParseErrorType::EINVAL,
+                                    String::new(),
+                                    0,
+                                ))
+                            }
                         };
                         unit = "";
                     }
@@ -569,14 +635,26 @@ impl UnitParseUtil {
                     Some(idx) => {
                         integer = match s[..idx].parse::<u64>() {
                             Ok(val) => val,
-                            Err(_) => return Err(ParseError::EINVAL),
+                            Err(_) => {
+                                return Err(ParseError::new(
+                                    ParseErrorType::EINVAL,
+                                    String::new(),
+                                    0,
+                                ))
+                            }
                         };
                         unit = &s[idx..];
                     }
                     None => {
                         integer = match s.parse::<u64>() {
                             Ok(val) => val,
-                            Err(_) => return Err(ParseError::EINVAL),
+                            Err(_) => {
+                                return Err(ParseError::new(
+                                    ParseErrorType::EINVAL,
+                                    String::new(),
+                                    0,
+                                ))
+                            }
                         };
                         unit = "";
                     }
@@ -588,7 +666,7 @@ impl UnitParseUtil {
         let factor = match SEC_UNIT_TABLE.get(unit) {
             Some(val) => val,
             None => {
-                return Err(ParseError::EINVAL);
+                return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
             }
         };
 

+ 3 - 1
src/task/cmdtask/mod.rs

@@ -1,4 +1,6 @@
-//use drstd as std;
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
 use std::string::String;
 
 #[derive(Debug)]

+ 256 - 22
src/unit/mod.rs

@@ -1,9 +1,18 @@
 use crate::error::ParseError;
+use crate::error::ParseErrorType;
+use crate::parse::parse_util::UnitParseUtil;
 use crate::parse::Segment;
-//use drstd as std;
+
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
 use std::any::Any;
 use std::boxed::Box;
+use std::default::Default;
 use std::rc::Rc;
+use std::result::Result;
+use std::result::Result::Err;
+use std::result::Result::Ok;
 use std::string::String;
 use std::vec::Vec;
 
@@ -32,13 +41,25 @@ pub trait Unit {
     /// 设置对应Unit属性
     ///
     /// @param segment  属性段类型
-    /// 
+    ///
     /// @param attr     属性名
-    /// 
+    ///
     /// @param val      属性值
     ///
     /// @return 设置成功则返回Ok(()),否则返回Err
     fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError>;
+
+    /// # 设置每个Unit都应该有的属性
+    ///
+    /// 设置BaseUnit
+    ///
+    /// ## param unit_base  设置值
+    fn set_unit_base(&mut self, unit_base: BaseUnit);
+
+    /// # 获取UnitType
+    ///
+    /// ## return UnitType
+    fn unit_type(&self) -> UnitType;
 }
 
 //Unit状态
@@ -70,10 +91,10 @@ pub enum UnitType {
 
 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性
 pub struct BaseUnit {
-    pub unit_part: UnitPart,
-    pub install_part: InstallPart,
-    pub state: UnitState,
-    pub unit_type: UnitType,
+    unit_part: UnitPart,
+    install_part: InstallPart,
+    state: UnitState,
+    unit_type: UnitType,
 }
 
 impl Default for BaseUnit {
@@ -88,12 +109,52 @@ impl Default for BaseUnit {
 }
 
 impl BaseUnit {
+    pub fn set_state(&mut self, state: UnitState) {
+        self.state = state;
+    }
+
+    pub fn set_unit_type(&mut self, utype: UnitType) {
+        self.unit_type = utype;
+    }
+
+    pub fn set_unit_part_attr(
+        &mut self,
+        attr_type: &BaseUnitAttr,
+        val: &str,
+    ) -> Result<(), ParseError> {
+        return self.unit_part.set_attr(attr_type, val);
+    }
+
+    pub fn set_install_part_attr(
+        &mut self,
+        attr_type: &InstallUnitAttr,
+        val: &str,
+    ) -> Result<(), ParseError> {
+        return self.install_part.set_attr(attr_type, val);
+    }
+
     pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> {
         return Ok(());
     }
+
+    pub fn unit_part(&self) -> &UnitPart {
+        &self.unit_part
+    }
+
+    pub fn install_part(&self) -> &InstallPart {
+        &self.install_part
+    }
+
+    pub fn state(&self) -> &UnitState {
+        &self.state
+    }
+
+    pub fn unit_type(&self) -> &UnitType {
+        &self.unit_type
+    }
 }
 
-#[derive(Default)]
+#[derive(Default,Debug)]
 pub struct Url {
     pub url_string: String, // pub protocol: String,
                             // pub host: String,
@@ -105,16 +166,16 @@ pub struct Url {
 
 //对应Unit文件的Unit段
 pub struct UnitPart {
-    pub description: String,
-    pub documentation: Vec<Url>,
-    pub requires: Vec<Rc<dyn Unit>>,
-    pub wants: Vec<Rc<dyn Unit>>,
-    pub after: Vec<Rc<dyn Unit>>,
-    pub before: Vec<Rc<dyn Unit>>,
-    pub binds_to: Vec<Rc<dyn Unit>>,
-    pub part_of: Vec<Rc<dyn Unit>>,
-    pub on_failure: Vec<Rc<dyn Unit>>,
-    pub conflicts: Vec<Rc<dyn Unit>>,
+    description: String,
+    documentation: Vec<Url>,
+    requires: Vec<Rc<dyn Unit>>,
+    wants: Vec<Rc<dyn Unit>>,
+    after: Vec<Rc<dyn Unit>>,
+    before: Vec<Rc<dyn Unit>>,
+    binds_to: Vec<Rc<dyn Unit>>,
+    part_of: Vec<Rc<dyn Unit>>,
+    on_failure: Vec<Rc<dyn Unit>>,
+    conflicts: Vec<Rc<dyn Unit>>,
 }
 
 impl Default for UnitPart {
@@ -134,12 +195,131 @@ impl Default for UnitPart {
     }
 }
 
+impl UnitPart {
+    pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> {
+        match attr {
+            BaseUnitAttr::None => {
+                return Err(ParseError::new(ParseErrorType::ESyntaxError,String::new(),0));
+            }
+            BaseUnitAttr::Description => self.description = String::from(val),
+            BaseUnitAttr::Documentation => {
+                self.documentation.extend(UnitParseUtil::parse_url(val)?)
+            }
+            BaseUnitAttr::Requires => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.requires
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::Wants => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.wants
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::After => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.after
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::Before => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.before
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::BindsTo => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.binds_to
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::PartOf => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.part_of
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::OnFailure => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    self.on_failure
+                        .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
+                }
+            }
+            BaseUnitAttr::Conflicts => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
+                    self.conflicts.push(unit);
+                }
+            }
+        }
+        return Ok(());
+    }
+
+    pub fn description(&self) -> &str {
+        &self.description
+    }
+
+    pub fn documentation(&self) -> &[Url] {
+        &self.documentation
+    }
+
+    pub fn requires(&self) -> &[Rc<dyn Unit>] {
+        &self.requires
+    }
+
+    pub fn wants(&self) -> &[Rc<dyn Unit>] {
+        &self.wants
+    }
+
+    pub fn after(&self) -> &[Rc<dyn Unit>] {
+        &self.after
+    }
+
+    pub fn before(&self) -> &[Rc<dyn Unit>] {
+        &self.before
+    }
+
+    pub fn binds_to(&self) -> &[Rc<dyn Unit>] {
+        &self.binds_to
+    }
+
+    pub fn part_of(&self) -> &[Rc<dyn Unit>] {
+        &self.part_of
+    }
+
+    pub fn on_failure(&self) -> &[Rc<dyn Unit>] {
+        &self.on_failure
+    }
+
+    pub fn conflicts(&self) -> &[Rc<dyn Unit>] {
+        &self.conflicts
+    }
+}
+
 //对应Unit文件的Install段
 pub struct InstallPart {
-    pub wanted_by: Vec<Rc<TargetUnit>>,
-    pub requires_by: Vec<Rc<TargetUnit>>,
-    pub also: Vec<Rc<dyn Unit>>,
-    pub alias: String,
+    wanted_by: Vec<Rc<TargetUnit>>,
+    requires_by: Vec<Rc<TargetUnit>>,
+    also: Vec<Rc<dyn Unit>>,
+    alias: String,
 }
 
 impl Default for InstallPart {
@@ -153,6 +333,60 @@ impl Default for InstallPart {
     }
 }
 
+impl InstallPart {
+    pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> {
+        match attr {
+            InstallUnitAttr::RequiredBy => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
+                    self.requires_by.push(unit);
+                }
+            }
+            InstallUnitAttr::Also => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
+                    self.also.push(unit);
+                }
+            }
+            InstallUnitAttr::WantedBy => {
+                let units = val.split_whitespace().collect::<Vec<&str>>();
+                //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
+                for unit_path in units {
+                    let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
+                    self.wanted_by.push(unit);
+                }
+            }
+            InstallUnitAttr::Alias => {
+                self.alias = String::from(val);
+            }
+            InstallUnitAttr::None => {
+                return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+            }
+        }
+        return Ok(());
+    }
+
+    pub fn wanted_by(&self) -> &[Rc<TargetUnit>] {
+        &self.wanted_by
+    }
+
+    pub fn requires_by(&self) -> &[Rc<TargetUnit>] {
+        &self.requires_by
+    }
+
+    pub fn also(&self) -> &[Rc<dyn Unit>] {
+        &self.also
+    }
+
+    pub fn alias(&self) -> &str {
+        &self.alias
+    }
+}
+
 //对应Unit文件的各种属性
 pub enum BaseUnitAttr {
     None,

+ 230 - 27
src/unit/service/mod.rs

@@ -1,16 +1,20 @@
 use super::{BaseUnit, Unit};
-use crate::error::ParseError;
+use crate::error::{ParseError, ParseErrorType};
 use crate::parse::parse_service::ServiceParser;
-use crate::parse::{AttrParse, Segment};
+use crate::parse::parse_util::UnitParseUtil;
+use crate::parse::{Segment, SERVICE_UNIT_ATTR_TABLE};
 use crate::task::cmdtask::CmdTask;
-//use drstd as std;
+
+#[cfg(target_os = "dragonos")]
+use drstd as std;
+
 use std::rc::Rc;
 use std::string::String;
 use std::vec::Vec;
 #[derive(Default)]
 pub struct ServiceUnit {
-    pub unit_base: BaseUnit,
-    pub service_part: ServicePart,
+    unit_base: BaseUnit,
+    service_part: ServicePart,
 }
 
 #[derive(Debug)]
@@ -62,28 +66,28 @@ impl Default for MountFlag {
 #[derive(Default, Debug)]
 pub struct ServicePart {
     //生命周期相关
-    pub service_type: ServiceType,
+    service_type: ServiceType,
     ///
-    pub remain_after_exit: bool,
-    pub exec_start: Vec<CmdTask>,
-    pub exec_start_pre: Vec<CmdTask>,
-    pub exec_start_pos: Vec<CmdTask>,
-    pub exec_reload: Vec<CmdTask>,
-    pub exec_stop: Vec<CmdTask>,
-    pub exec_stop_post: Vec<CmdTask>,
-    pub restart_sec: u64,
-    pub restart: RestartOption,
-    pub timeout_start_sec: u64,
-    pub timeout_stop_sec: u64,
+    remain_after_exit: bool,
+    exec_start: Vec<CmdTask>,
+    exec_start_pre: Vec<CmdTask>,
+    exec_start_pos: Vec<CmdTask>,
+    exec_reload: Vec<CmdTask>,
+    exec_stop: Vec<CmdTask>,
+    exec_stop_post: Vec<CmdTask>,
+    restart_sec: u64,
+    restart: RestartOption,
+    timeout_start_sec: u64,
+    timeout_stop_sec: u64,
     //上下文配置相关
-    pub environment: String,
-    pub environment_file: String,
-    pub nice: i8,
-    pub working_directory: String,
-    pub root_directory: String,
-    pub user: String,
-    pub group: String,
-    pub mount_flags: MountFlag,
+    environment: Vec<String>,
+    environment_file: String,
+    nice: i8,
+    working_directory: String,
+    root_directory: String,
+    user: String,
+    group: String,
+    mount_flags: MountFlag,
     //LimitCPU / LimitSTACK / LimitNOFILE / LimitNPROC 等,后续支持再添加
 }
 
@@ -101,9 +105,28 @@ impl Unit for ServiceUnit {
 
     fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError> {
         if segment != Segment::Service {
-            return Err(ParseError::EINVAL);
+            return Err(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
         }
-        return ServiceParser::parse_and_set_attribute(self, attr, val);
+        let attr_type = SERVICE_UNIT_ATTR_TABLE.get(attr).ok_or(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
+        return self.service_part.set_attr(attr_type.unwrap(), val);
+    }
+
+    fn set_unit_base(&mut self, base: BaseUnit) {
+        self.unit_base = base;
+    }
+
+    fn unit_type(&self) -> super::UnitType {
+        return self.unit_base.unit_type;
+    }
+}
+
+impl ServiceUnit {
+    pub fn unit_base(&self) -> &BaseUnit {
+        return &self.unit_base;
+    }
+
+    pub fn service_part(&self) -> &ServicePart {
+        return &self.service_part;
     }
 }
 
@@ -151,3 +174,183 @@ pub enum ServiceUnitAttr {
     //服务的 Mount Namespace 配置,会影响进程上下文中挂载点的信息
     MountFlags,
 }
+
+impl ServicePart {
+    pub fn set_attr(&mut self, attr: &ServiceUnitAttr, val: &str) -> Result<(), ParseError> {
+        match attr {
+            ServiceUnitAttr::Type => match val {
+                "simple" => self.service_type = ServiceType::Simple,
+                "forking" => self.service_type = ServiceType::Forking,
+                "oneshot" => self.service_type = ServiceType::OneShot,
+                "dbus" => self.service_type = ServiceType::Dbus,
+                "notify" => self.service_type = ServiceType::Notify,
+                "idle" => self.service_type = ServiceType::Idle,
+                _ => {
+                    return Err(ParseError::new(ParseErrorType::EINVAL, String::new(),0));
+                }
+            },
+            ServiceUnitAttr::RemainAfterExit => {
+                self.remain_after_exit = UnitParseUtil::parse_boolean(val)?
+            }
+            ServiceUnitAttr::ExecStart => {
+                self.exec_start.extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::ExecStartPre => {
+                self.exec_start_pre
+                    .extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::ExecStartPos => {
+                self.exec_start_pos
+                    .extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::ExecReload => {
+                self.exec_reload.extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::ExecStopPost => {
+                self.exec_stop_post
+                    .extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::ExecStop => {
+                self.exec_stop.extend(UnitParseUtil::parse_cmd_task(val)?);
+            }
+            ServiceUnitAttr::RestartSec => self.restart_sec = UnitParseUtil::parse_sec(val)?,
+            ServiceUnitAttr::Restart => match val {
+                "always" => self.restart = RestartOption::AlwaysRestart,
+                "on-success" => self.restart = RestartOption::OnSuccess,
+                "on-failure" => self.restart = RestartOption::OnFailure,
+                "on-abnormal" => self.restart = RestartOption::OnAbnormal,
+                "on-abort" => self.restart = RestartOption::OnAbort,
+                "on-watchdog" => self.restart = RestartOption::OnWatchdog,
+                _ => {
+                    return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                }
+            },
+            ServiceUnitAttr::TimeoutStartSec => {
+                self.timeout_start_sec = UnitParseUtil::parse_sec(val)?
+            }
+            ServiceUnitAttr::TimeoutStopSec => {
+                self.timeout_stop_sec = UnitParseUtil::parse_sec(val)?
+            }
+            ServiceUnitAttr::Environment => {
+                self.environment.push(String::from(val));
+            }
+            ServiceUnitAttr::EnvironmentFile => {
+                if !UnitParseUtil::is_valid_file(val) {
+                    return Err(ParseError::new(ParseErrorType::EFILE,String::new(),0));
+                }
+                self.environment_file = String::from(val);
+            }
+            ServiceUnitAttr::Nice => {
+                self.nice = UnitParseUtil::parse_nice(val)?;
+            }
+            ServiceUnitAttr::WorkingDirectory => {
+                if !UnitParseUtil::is_dir(val) {
+                    return Err(ParseError::new(ParseErrorType::ENODIR,String::new(),0));
+                }
+                self.working_directory = String::from(val);
+            }
+            ServiceUnitAttr::User => {
+                //TODO: 检查系统是否存在这个用户
+                self.user = String::from(val);
+            }
+            ServiceUnitAttr::Group => {
+                //TODO: 检查系统是否存在该用户组
+                self.group = String::from(val);
+            }
+            ServiceUnitAttr::MountFlags => match val {
+                "shared" => self.mount_flags = MountFlag::Shared,
+                "slave" => self.mount_flags = MountFlag::Slave,
+                "private" => self.mount_flags = MountFlag::Private,
+                _ => {
+                    return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+                }
+            },
+            _ => {
+                return Err(ParseError::new(ParseErrorType::EINVAL,String::new(),0));
+            }
+        }
+        return Ok(());
+    }
+
+    // 生命周期相关
+    pub fn service_type(&self) -> &ServiceType {
+        &self.service_type
+    }
+
+    pub fn remain_after_exit(&self) -> bool {
+        self.remain_after_exit
+    }
+
+    pub fn exec_start(&self) -> &Vec<CmdTask> {
+        &self.exec_start
+    }
+
+    pub fn exec_start_pre(&self) -> &Vec<CmdTask> {
+        &self.exec_start_pre
+    }
+
+    pub fn exec_start_pos(&self) -> &Vec<CmdTask> {
+        &self.exec_start_pos
+    }
+
+    pub fn exec_reload(&self) -> &Vec<CmdTask> {
+        &self.exec_reload
+    }
+
+    pub fn exec_stop(&self) -> &Vec<CmdTask> {
+        &self.exec_stop
+    }
+
+    pub fn exec_stop_post(&self) -> &Vec<CmdTask> {
+        &self.exec_stop_post
+    }
+
+    pub fn restart_sec(&self) -> u64 {
+        self.restart_sec
+    }
+
+    pub fn restart(&self) -> &RestartOption {
+        &self.restart
+    }
+
+    pub fn timeout_start_sec(&self) -> u64 {
+        self.timeout_start_sec
+    }
+
+    pub fn timeout_stop_sec(&self) -> u64 {
+        self.timeout_stop_sec
+    }
+
+    // 上下文配置相关
+    pub fn environment(&self) -> &[String] {
+        &self.environment
+    }
+
+    pub fn environment_file(&self) -> &str {
+        &self.environment_file
+    }
+
+    pub fn nice(&self) -> i8 {
+        self.nice
+    }
+
+    pub fn working_directory(&self) -> &str {
+        &self.working_directory
+    }
+
+    pub fn root_directory(&self) -> &str {
+        &self.root_directory
+    }
+
+    pub fn user(&self) -> &str {
+        &self.user
+    }
+
+    pub fn group(&self) -> &str {
+        &self.group
+    }
+
+    pub fn mount_flags(&self) -> &MountFlag {
+        &self.mount_flags
+    }
+}

+ 23 - 6
src/unit/target/mod.rs

@@ -1,16 +1,25 @@
 use super::{BaseUnit, Unit};
 use crate::error::ParseError;
 use crate::parse::Segment;
+use crate::parse::parse_target::TargetParser;
 use core::ops::Deref;
-//use drstd as std;
-use std::boxed::Box;
-use std::rc::Rc;
-use std::vec::Vec;
+use cfg_if::cfg_if;
+
+cfg_if!{
+    if #[cfg(target_os = "dragonos")]{
+        use drstd as std;
+        use std::rc::Rc;
+        use std::vec::Vec;
+    }else{
+        use std::rc::Rc;
+        use std::vec::Vec;
+    }
+}
 
 #[derive(Default)]
 pub struct TargetUnit {
     unit_base: BaseUnit,
-    targets: Vec<Rc<dyn Unit>>,
+    //targets: Vec<Rc<dyn Unit>>,
 }
 
 impl Deref for TargetUnit {
@@ -29,10 +38,18 @@ impl Unit for TargetUnit {
     where
         Self: Sized,
     {
-        Ok(Rc::new(TargetUnit::default()))
+        return TargetParser::parse(path);
     }
 
     fn set_attr(&mut self, segement: Segment, attr: &str, val: &str) -> Result<(), ParseError> {
         Ok(())
     }
+
+    fn set_unit_base(&mut self, base: BaseUnit) {
+        self.unit_base = base;
+    }
+
+    fn unit_type(&self) -> super::UnitType {
+        return self.unit_base.unit_type;
+    }
 }