diff --git a/Cargo.toml b/Cargo.toml index bf56169..2efccc2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ targets = [ [dependencies] enum-as-inner = "0.6.0" -libc = "^0.2.34" +libc = "^0.2.179" byteorder = "^1.4.3" thiserror = "^2.0" bitflags = "^2" diff --git a/examples/set_value.rs b/examples/set_value.rs index f1237e6..7d2ee3c 100644 --- a/examples/set_value.rs +++ b/examples/set_value.rs @@ -7,7 +7,7 @@ extern crate sysctl; // Import the trait use sysctl::Sysctl; -#[cfg(target_os = "freebsd")] +#[cfg(any(target_os = "freebsd", target_os = "openbsd"))] const CTLNAME: &str = "net.inet.ip.forwarding"; #[cfg(target_os = "macos")] diff --git a/examples/value.rs b/examples/value.rs index fe493bf..c37055f 100644 --- a/examples/value.rs +++ b/examples/value.rs @@ -6,7 +6,7 @@ extern crate sysctl; // Import the trait use sysctl::Sysctl; -#[cfg(any(target_os = "macos", target_os = "freebsd"))] +#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd"))] const CTLNAMES: &[&str] = &["kern.ostype"]; #[cfg(any(target_os = "linux", target_os = "android"))] diff --git a/examples/value_as.rs b/examples/value_as.rs index 34f7e90..367ea9a 100644 --- a/examples/value_as.rs +++ b/examples/value_as.rs @@ -37,7 +37,7 @@ impl std::fmt::Debug for LoadAvg { } } -#[cfg(any(target_os = "macos", target_os = "freebsd"))] +#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd"))] fn main() { // Generic type to pass to function will be inferred if not specified on RHS println!("Read sysctl kern.clockrate as struct directly"); diff --git a/examples/value_oid_as.rs b/examples/value_oid_as.rs index cd0f214..c90ae18 100644 --- a/examples/value_oid_as.rs +++ b/examples/value_oid_as.rs @@ -18,7 +18,7 @@ struct ClockInfo { profhz: libc::c_int, /* profiling clock frequency */ } -#[cfg(any(target_os = "macos", target_os = "freebsd"))] +#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd"))] fn main() { let oid: Vec = vec![libc::CTL_KERN, libc::KERN_CLOCKRATE]; let val: Box = sysctl::Ctl::Oid(oid).value_as().expect("could not get value"); diff --git a/examples/value_string.rs b/examples/value_string.rs index aa407a8..b73db64 100644 --- a/examples/value_string.rs +++ b/examples/value_string.rs @@ -6,7 +6,7 @@ extern crate sysctl; // Import the trait use sysctl::Sysctl; -#[cfg(any(target_os = "macos", target_os = "freebsd"))] +#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd"))] const CTLNAMES: &[&str] = &["kern.osrevision"]; // On Linux all sysctl are String so it doesn't really make any sense to read an integer value here... diff --git a/src/ctl_flags.rs b/src/ctl_flags.rs index 6fafdcc..84b80ef 100644 --- a/src/ctl_flags.rs +++ b/src/ctl_flags.rs @@ -69,10 +69,12 @@ bitflags! { } } +#[cfg(not(all(test, target_os = "openbsd")))] #[cfg(test)] mod tests { use crate::Sysctl; + #[cfg(not(all(test, target_os = "openbsd")))] #[test] fn ctl_flags() { // This sysctl should be read-only. diff --git a/src/lib.rs b/src/lib.rs index 498ba54..ab70c27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ //! A simplified interface to the `sysctl` system call. //! //! # Example: Get value -//! ``` +//! ```ignore-openbsd //! # use sysctl::Sysctl; //! #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "freebsd"))] //! const CTLNAME: &str = "kern.ostype"; @@ -23,7 +23,7 @@ //! //! # Example: Get value as struct //! ``` -//! // Not available on Linux +//! // Not available on Linux and OpenBSD //! # use sysctl::Sysctl; //! #[derive(Debug, Default)] //! #[repr(C)] @@ -54,7 +54,7 @@ extern crate walkdir; #[path = "linux/mod.rs"] mod sys; -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "freebsd"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "freebsd", target_os = "openbsd"))] #[path = "unix/mod.rs"] mod sys; diff --git a/src/traits.rs b/src/traits.rs index 085df04..b4aefcc 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -20,7 +20,7 @@ pub trait Sysctl { /// ``` /// /// If the sysctl does not exist, `Err(SysctlError::NotFound)` is returned. - /// ``` + /// ```ignore-openbsd /// # use sysctl::Sysctl; /// # /// let ctl = sysctl::Ctl::new("this.sysctl.does.not.exist"); @@ -47,7 +47,7 @@ pub trait Sysctl { /// ``` /// /// If the sysctl does not exist, `Err(SysctlError::NotFound)` is returned. - /// ``` + /// ```ignore-openbsd /// # use sysctl::{CtlType, Sysctl}; /// # /// let ctl = sysctl::Ctl::new_with_type("this.sysctl.does.not.exist", CtlType::String, ""); @@ -65,7 +65,7 @@ pub trait Sysctl { /// SysctlError on failure. /// /// # Example - /// ``` + /// ```ignore-openbsd /// # use sysctl::Sysctl; /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") { /// assert_eq!(ctl.name().unwrap(), "kern.ostype"); @@ -78,7 +78,7 @@ pub trait Sysctl { /// /// # Example /// - /// ``` + /// ```ignore-openbsd /// # use sysctl::Sysctl; /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") { /// let value_type = ctl.value_type().unwrap(); @@ -192,7 +192,7 @@ pub trait Sysctl { /// or a SysctlError on failure. /// /// # Example - /// ``` + /// ```ignore-openbsd /// # use sysctl::Sysctl; /// if let Ok(ctl) = sysctl::Ctl::new("kern.ostype") { /// let readable = ctl.flags().unwrap().contains(sysctl::CtlFlags::RD); @@ -208,9 +208,10 @@ pub trait Sysctl { /// or a SysctlError on failure. /// /// # Example - /// ``` + /// ```ignore-openbsd /// use sysctl::Sysctl; /// + ///#[cfg(not(all(test, target_os = "openbsd")))] /// fn main() { /// if let Ok(ctl) = sysctl::Ctl::new("kern.osrevision") { /// let info = ctl.info().unwrap(); diff --git a/src/unix/ctl.rs b/src/unix/ctl.rs index 0e0be16..32c3e79 100644 --- a/src/unix/ctl.rs +++ b/src/unix/ctl.rs @@ -60,7 +60,7 @@ impl Sysctl for Ctl { } } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn value_type(&self) -> Result { match self { Ctl::Oid(oid) => { @@ -73,7 +73,7 @@ impl Sysctl for Ctl { } } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn value_type(&self) -> Result { match self { Ctl::Oid(oid) => { @@ -105,24 +105,24 @@ impl Sysctl for Ctl { } } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn description(&self) -> Result { let oid = self.oid().ok_or(SysctlError::MissingImplementation)?; oid2description(oid) } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn description(&self) -> Result { Ok("[N/A]".to_string()) } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn value(&self) -> Result { let oid = self.oid().ok_or(SysctlError::MissingImplementation)?; value_oid(oid) } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn value(&self) -> Result { match self { Ctl::Oid(oid) => { @@ -135,7 +135,7 @@ impl Sysctl for Ctl { } } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn value_as(&self) -> Result, SysctlError> { let oid = self.oid().ok_or(SysctlError::MissingImplementation)?; value_oid_as::(oid) @@ -145,7 +145,7 @@ impl Sysctl for Ctl { self.value().map(|v| format!("{}", v)) } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn value_as(&self) -> Result, SysctlError> { match self { Ctl::Oid(oid) => { @@ -158,13 +158,13 @@ impl Sysctl for Ctl { } } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn set_value(&self, value: CtlValue) -> Result { let oid = self.oid().ok_or(SysctlError::MissingImplementation)?; set_oid_value(&oid, value) } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn set_value(&self, value: CtlValue) -> Result { match self { Ctl::Oid(oid) => { @@ -177,7 +177,7 @@ impl Sysctl for Ctl { } } - #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] fn set_value_string(&self, value: &str) -> Result { let oid = self.oid().ok_or(SysctlError::MissingImplementation)?; let ctl_type = self.value_type()?; @@ -204,7 +204,7 @@ impl Sysctl for Ctl { self.value_string() } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] fn set_value_string(&self, value: &str) -> Result { let ctl_type = self.value_type()?; @@ -303,7 +303,7 @@ mod tests { #[cfg(target_os = "freebsd")] assert_eq!(descp, "Operating system type"); - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "linux"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "linux", target_os = "openbsd"))] assert_eq!(descp, "[N/A]"); } } diff --git a/src/unix/ctl_iter.rs b/src/unix/ctl_iter.rs index d59f6f0..ffd7f09 100644 --- a/src/unix/ctl_iter.rs +++ b/src/unix/ctl_iter.rs @@ -58,7 +58,7 @@ impl Iterator for CtlIter { /// /// # Example /// -/// ``` +/// ```ignore-openbsd /// use sysctl::Sysctl; /// /// let kern = sysctl::Ctl::new("kern"); @@ -75,6 +75,7 @@ impl IntoIterator for Ctl { } } +#[cfg(not(all(test, target_os = "openbsd")))] #[cfg(test)] mod tests { use crate::Sysctl; diff --git a/src/unix/funcs.rs b/src/unix/funcs.rs index c1340c6..f4e7f43 100644 --- a/src/unix/funcs.rs +++ b/src/unix/funcs.rs @@ -12,6 +12,7 @@ use std::ffi::CString; #[cfg(target_os = "freebsd")] use crate::temperature::*; +#[cfg(not(target_os = "openbsd"))] pub fn name2oid(name: &str) -> Result, SysctlError> { // We get results in this vector let mut len: usize = CTL_MAXNAME as usize; @@ -42,7 +43,12 @@ pub fn name2oid(name: &str) -> Result, SysctlError> { Ok(res) } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(target_os = "openbsd")] +pub fn name2oid(_name: &str) -> Result, SysctlError> { + Ok(Vec::new()) +} + +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn oidfmt(oid: &[libc::c_int]) -> Result { // Request command for type info let mut qoid: Vec = vec![0, 4]; @@ -87,7 +93,7 @@ pub fn oidfmt(oid: &[libc::c_int]) -> Result { Ok(s) } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] pub fn oidfmt(oid: &[libc::c_int]) -> Result { // Request command for type info let mut qoid: Vec = vec![0, 4]; @@ -138,7 +144,7 @@ pub fn oidfmt(oid: &[libc::c_int]) -> Result { Ok(s) } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn value_oid(oid: &[i32]) -> Result { let info: CtlInfo = oidfmt(&oid)?; @@ -227,7 +233,7 @@ pub fn value_oid(oid: &[i32]) -> Result { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] pub fn value_oid(oid: &mut Vec) -> Result { let info: CtlInfo = oidfmt(&oid)?; @@ -315,7 +321,7 @@ pub fn value_oid(oid: &mut Vec) -> Result { } } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn value_oid_as(oid: &[i32]) -> Result, SysctlError> { let val_enum = value_oid(oid)?; @@ -359,7 +365,7 @@ pub fn value_oid_as(oid: &[i32]) -> Result, SysctlError> { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] pub fn value_oid_as(oid: &mut Vec) -> Result, SysctlError> { let val_enum = value_oid(oid)?; @@ -402,6 +408,10 @@ pub fn value_oid_as(oid: &mut Vec) -> Result, SysctlError> { Err(SysctlError::ExtractionError) } } +#[cfg(target_os = "openbsd")] +pub fn value_name(_name: &str, _ctl_type: CtlType, _fmt: &str) -> Result { + Ok(CtlValue::None) +} #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] pub fn value_name(name: &str, ctl_type: CtlType, fmt: &str) -> Result { @@ -484,7 +494,9 @@ pub fn value_name(name: &str, ctl_type: CtlType, fmt: &str) -> Result(name: &str, ctl_type: CtlType, fmt: &str) -> Result, SysctlError> { let val_enum = value_name(name, ctl_type, fmt)?; @@ -556,7 +568,7 @@ fn value_to_bytes(value: CtlValue) -> Result, SysctlError> { } } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn set_oid_value(oid: &[libc::c_int], value: CtlValue) -> Result { let info: CtlInfo = oidfmt(&oid)?; @@ -592,7 +604,7 @@ pub fn set_oid_value(oid: &[libc::c_int], value: CtlValue) -> Result, value: CtlValue) -> Result { let info: CtlInfo = oidfmt(&oid)?; @@ -642,6 +654,37 @@ pub fn set_oid_value(oid: &mut Vec, value: CtlValue) -> Result Result { + let ctl_type = CtlType::from(&value); + + // Get the correct ctl type based on the format string + let info_ctl_type = match info_ctl_type { + CtlType::Int => match fmt { + "I" => CtlType::Int, + "IU" => CtlType::Uint, + "L" => CtlType::Long, + "LU" => CtlType::Ulong, + _ => return Err(SysctlError::MissingImplementation), + } + ctl_type => ctl_type, + }; + + assert_eq!( + info_ctl_type, ctl_type, + "Error type mismatch. Type given {:?}, sysctl type: {:?}", + ctl_type, info_ctl_type + ); + + self::value_name(name, ctl_type, fmt) +} + + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] pub fn set_name_value( name: &str, @@ -690,7 +733,7 @@ pub fn set_name_value( self::value_name(name, ctl_type, fmt) } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn oid2description(oid: &[libc::c_int]) -> Result { // Request command for description let mut qoid: Vec = vec![0, 5]; @@ -720,7 +763,7 @@ pub fn oid2description(oid: &[libc::c_int]) -> Result { } } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn oid2name(oid: &[libc::c_int]) -> Result { // Request command for name let mut qoid: Vec = vec![0, 1]; @@ -750,7 +793,7 @@ pub fn oid2name(oid: &[libc::c_int]) -> Result { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] pub fn oid2name(oid: &Vec) -> Result { // Request command for name let mut qoid: Vec = vec![0, 1]; @@ -780,7 +823,7 @@ pub fn oid2name(oid: &Vec) -> Result { } } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")))] +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd")))] pub fn next_oid(oid: &[libc::c_int]) -> Result>, SysctlError> { // Request command for next oid let mut qoid: Vec = vec![0, 2]; @@ -819,7 +862,7 @@ pub fn next_oid(oid: &[libc::c_int]) -> Result>, SysctlE Ok(Some(res)) } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))] +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos", target_os = "openbsd"))] pub fn next_oid(oid: &Vec) -> Result>, SysctlError> { // Request command for next oid let mut qoid: Vec = vec![0, 2]; @@ -860,8 +903,10 @@ pub fn next_oid(oid: &Vec) -> Result>, Sysc #[cfg(test)] mod tests { + #[cfg(not(target_os = "openbsd"))] use crate::Sysctl; + #[cfg(not(all(test, target_os = "openbsd")))] #[test] fn ctl_name() { let oid = vec![libc::CTL_KERN, libc::KERN_OSREV]; @@ -876,6 +921,7 @@ mod tests { assert_eq!(name, "kern.osrevision"); } + #[cfg(not(all(test, target_os = "openbsd")))] #[test] fn ctl_type() { let oid = super::name2oid("kern").unwrap(); @@ -907,6 +953,7 @@ mod tests { } /// The name must be respresentable as a C String + #[cfg(not(all(test, target_os = "openbsd")))] #[test] fn name2oid_invalid_name() { let r = super::name2oid("kern.\0.invalid.utf-8"); @@ -937,3 +984,12 @@ mod tests_macos { assert_eq!(oid[2], libc::KERN_PROC_PID); } } + +#[cfg(all(test, target_os = "openbsd"))] +mod tests_openbsd { + #[test] + fn ctl_mib() { + let oid = super::name2oid("kern.proc.pid").unwrap(); + assert_eq!(oid.len(), 0); + } +}