diff --git a/test/integration-test/Cargo.toml b/test/integration-test/Cargo.toml index 07eaa927..09770325 100644 --- a/test/integration-test/Cargo.toml +++ b/test/integration-test/Cargo.toml @@ -13,6 +13,5 @@ libc = { version = "0.2.105" } log = "0.4" object = { version = "0.31", default-features = false, features = ["std", "read_core", "elf"] } rbpf = "0.2.0" -regex = "1" tempfile = "3.3.0" tokio = { version = "1.24", features = ["rt", "rt-multi-thread", "sync", "time"] } diff --git a/test/integration-test/tests/common.rs b/test/integration-test/tests/common.rs index 3af8a597..958b3169 100644 --- a/test/integration-test/tests/common.rs +++ b/test/integration-test/tests/common.rs @@ -1,23 +1,42 @@ -use anyhow::bail; +use anyhow::{anyhow, Context as _}; use libc::{uname, utsname}; -use regex::Regex; -use std::{cell::OnceCell, ffi::CStr, mem}; +use std::{ffi::CStr, io::Error, mem}; pub fn kernel_version() -> anyhow::Result<(u8, u8, u8)> { - static mut RE: OnceCell = OnceCell::new(); - let re = - unsafe { &mut RE }.get_or_init(|| Regex::new(r"^([0-9]+)\.([0-9]+)\.([0-9]+)").unwrap()); let mut data: utsname = unsafe { mem::zeroed() }; let ret = unsafe { uname(&mut data) }; - assert!(ret >= 0, "libc::uname failed."); - let release_cstr = unsafe { CStr::from_ptr(data.release.as_ptr()) }; - let release = release_cstr.to_string_lossy(); - if let Some(caps) = re.captures(&release) { - let major = caps.get(1).unwrap().as_str().parse().unwrap(); - let minor = caps.get(2).unwrap().as_str().parse().unwrap(); - let patch = caps.get(3).unwrap().as_str().parse().unwrap(); - Ok((major, minor, patch)) - } else { - bail!("no kernel version found"); + if ret != 0 { + return Err(Error::last_os_error()).context("uname failed"); } + let utsname { release, .. } = data; + let release: &[u8] = + unsafe { std::slice::from_raw_parts(release.as_ptr() as _, release.len()) }; + let s = CStr::from_bytes_until_nul(release)?; + let s = s.to_str()?; + + // Adapted from https://github.com/eminence/procfs/blob/d7ea846/procfs/src/sys/kernel/mod.rs#L51-L70. + let pos = s.find(|c: char| c != '.' && !c.is_ascii_digit()); + let kernel = if let Some(pos) = pos { + let (s, _) = s.split_at(pos); + s + } else { + s + }; + let mut kernel_split = kernel.split('.'); + + let major = kernel_split + .next() + .ok_or(anyhow!("Missing major version component"))?; + let minor = kernel_split + .next() + .ok_or(anyhow!("Missing minor version component"))?; + let patch = kernel_split + .next() + .ok_or(anyhow!("Missing patch version component"))?; + + let major = major.parse().context("Failed to parse major version")?; + let minor = minor.parse().context("Failed to parse minor version")?; + let patch = patch.parse().context("Failed to parse patch version")?; + + Ok((major, minor, patch)) }