sysctl/linux/
ctl.rs
1use super::funcs::{path_to_name, set_value, value};
4use consts::*;
5use ctl_error::SysctlError;
6use ctl_flags::CtlFlags;
7use ctl_info::CtlInfo;
8use ctl_type::CtlType;
9use ctl_value::CtlValue;
10use std::str::FromStr;
11use traits::Sysctl;
12
13#[derive(Debug, Clone, PartialEq)]
15pub struct Ctl {
16 name: String,
17}
18
19impl FromStr for Ctl {
20 type Err = SysctlError;
21
22 fn from_str(name: &str) -> Result<Self, Self::Err> {
23 let ctl = Ctl {
24 name: path_to_name(name),
25 };
26 let _ =
27 std::fs::File::open(ctl.path()).map_err(|_| SysctlError::NotFound(name.to_owned()))?;
28 Ok(ctl)
29 }
30}
31
32impl Ctl {
33 pub fn path(&self) -> String {
34 format!("/proc/sys/{}", self.name.replace(".", "/"))
35 }
36}
37
38impl Sysctl for Ctl {
39 fn new(name: &str) -> Result<Self, SysctlError> {
40 Ctl::from_str(name)
41 }
42
43 fn new_with_type(name: &str, _ctl_type: CtlType, _fmt: &str) -> Result<Self, SysctlError> {
44 Ctl::from_str(name)
45 }
46
47 fn name(&self) -> Result<String, SysctlError> {
48 Ok(self.name.clone())
49 }
50
51 fn value_type(&self) -> Result<CtlType, SysctlError> {
52 let md = std::fs::metadata(&self.path()).map_err(SysctlError::IoError)?;
53 if md.is_dir() {
54 Ok(CtlType::Node)
55 } else {
56 Ok(CtlType::String)
57 }
58 }
59
60 fn description(&self) -> Result<String, SysctlError> {
61 Ok("[N/A]".to_owned())
62 }
63
64 fn value(&self) -> Result<CtlValue, SysctlError> {
65 value(&self.path())
66 }
67
68 fn value_string(&self) -> Result<String, SysctlError> {
69 self.value().map(|v| format!("{}", v))
70 }
71
72 fn value_as<T>(&self) -> Result<Box<T>, SysctlError> {
73 Err(SysctlError::NotSupported)
74 }
75
76 fn set_value(&self, value: CtlValue) -> Result<CtlValue, SysctlError> {
77 set_value(&self.path(), value)
78 }
79
80 fn set_value_string(&self, value: &str) -> Result<String, SysctlError> {
81 self.set_value(CtlValue::String(value.to_owned()))?;
82 self.value_string()
83 }
84
85 fn flags(&self) -> Result<CtlFlags, SysctlError> {
86 Ok(self.info()?.flags())
87 }
88
89 fn info(&self) -> Result<CtlInfo, SysctlError> {
90 let md = std::fs::metadata(&self.path()).map_err(SysctlError::IoError)?;
91 let mut flags = 0;
92 if md.permissions().readonly() {
93 flags |= CTLFLAG_RD;
94 } else {
95 flags |= CTLFLAG_RW;
96 }
97 let s = CtlInfo {
98 ctl_type: CtlType::String,
99 fmt: "".to_owned(),
100 flags: flags,
101 };
102 Ok(s)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::Sysctl;
109
110 #[test]
111 fn ctl_new() {
112 let _ = super::Ctl::new("kernel.ostype").expect("Ctl::new");
113 }
114}