Skip to content

Commit

Permalink
add List type to address issue johalun#26 on FreeBSD
Browse files Browse the repository at this point in the history
  • Loading branch information
jyoung15 committed Apr 4, 2021
1 parent b712873 commit f38d0fe
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/ctl_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub enum CtlType {
None = 0,
#[cfg(target_os = "freebsd")]
Temperature = 16,
#[cfg(target_os = "freebsd")]
List = 17,
}
impl std::convert::From<u32> for CtlType {
fn from(t: u32) -> Self {
Expand Down Expand Up @@ -65,6 +67,8 @@ impl std::convert::From<&CtlValue> for CtlType {
&CtlValue::U32(_) => CtlType::U32,
#[cfg(target_os = "freebsd")]
&CtlValue::Temperature(_) => CtlType::Temperature,
#[cfg(target_os = "freebsd")]
&CtlValue::List(_) => CtlType::List,
}
}
}
Expand Down Expand Up @@ -97,6 +101,8 @@ impl CtlType {
// Added custom types below
#[cfg(target_os = "freebsd")]
&CtlType::Temperature => 0,
#[cfg(target_os = "freebsd")]
&CtlType::List => 0,
}
}
}
4 changes: 4 additions & 0 deletions src/ctl_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub enum CtlValue {
U32(u32),
#[cfg(target_os = "freebsd")]
Temperature(Temperature),
#[cfg(target_os = "freebsd")]
List(Vec<CtlValue>),
}

impl std::fmt::Display for CtlValue {
Expand All @@ -59,6 +61,8 @@ impl std::fmt::Display for CtlValue {
CtlValue::String(s) => s.to_owned(),
#[cfg(target_os = "freebsd")]
CtlValue::Temperature(t) => format!("{}", t.kelvin()),
#[cfg(target_os = "freebsd")]
CtlValue::List(_) => "[List]".to_owned(),
};
write!(f, "{}", s)
}
Expand Down
91 changes: 91 additions & 0 deletions src/unix/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,78 @@ pub fn value_oid(oid: &Vec<i32>) -> Result<CtlValue, SysctlError> {
return temperature(&info, &val);
}

// This only appears to be used on FreeBSD for kern.cp_time and kern.cp_times which are type Long
// Handling for other types may be unnecessary
#[cfg(target_os = "freebsd")]
{
let expected_length = info.ctl_type.min_type_size();
// check if sysctl returned a list of values (such as kern.cp_times)
if expected_length > 0 && new_val_len > expected_length {
assert_eq!(
new_val_len % expected_length,
0,
"Sysctl length {} is not evenly divisible by expected length for {:?} {}",
new_val_len,
info.ctl_type,
expected_length
);
let list_length: usize = new_val_len / expected_length;

macro_rules! ctl_match_arm {
( $tp:tt, read_u8 ) => {
Ok(CtlValue::List(
(0..list_length)
.map(|x| CtlValue::$tp(val[x]))
.collect::<Vec<CtlValue>>(),
))
};
( $tp:tt, read_i8 ) => {
Ok(CtlValue::List(
(0..list_length)
.map(|x| CtlValue::$tp(val[x] as i8))
.collect::<Vec<CtlValue>>(),
))
};
( $tp:tt, $fn:tt) => {
Ok(CtlValue::List(
(0..list_length)
.map(|x| {
CtlValue::$tp(byteorder::LittleEndian::$fn(
&val[x * expected_length..],
))
})
.collect::<Vec<CtlValue>>(),
))
};
}

macro_rules! ctl_expand_list {
($obj:expr, $( $tp:tt => $fn:tt ),*) => {
match $obj {
$(CtlType::$tp => ctl_match_arm!($tp, $fn)),*,
_ => Err(SysctlError::ExtractionError)
}
}
}

return ctl_expand_list!(
info.ctl_type,
Int => read_i32,
S64 => read_i64,
Uint => read_u32,
Long => read_i64,
Ulong => read_u64,
U64 => read_u64,
U8 => read_u8,
U16 => read_u16,
S8 => read_i8,
S16 => read_i16,
S32 => read_i32,
U32 => read_u32
);
}
}

// Wrap in Enum and return
match info.ctl_type {
CtlType::None => Ok(CtlValue::None),
Expand Down Expand Up @@ -759,6 +831,25 @@ mod tests_freebsd {
assert_eq!(oid[1], libc::KERN_PROC);
assert_eq!(oid[2], libc::KERN_PROC_PID);
}

#[test]
fn list_type_kern_cp_time() {
use traits::Sysctl;
let cp_time = crate::Ctl::new("kern.cp_time").unwrap().value().unwrap();
if let crate::CtlValue::List(list) = &cp_time {
/*
should contain 5 values for:
* user
* nice
* system
* interrupt
* idle
*/
assert_eq!(list.len(), 5);
}
let val_type: crate::CtlType = cp_time.into();
assert_eq!(val_type, crate::CtlType::List);
}
}

#[cfg(all(test, target_os = "macos"))]
Expand Down

0 comments on commit f38d0fe

Please sign in to comment.