Skip to content

Commit

Permalink
Several utils-related little refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
vrmiguel committed Jun 3, 2023
1 parent 491ee41 commit fab04c5
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 22 deletions.
1 change: 0 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub enum Error {
InvalidLinuxVersion,
MalformedStatm,
MalformedPressureFile,
StringFromBytes,
ParseInt,
ParseFloat,
SysConfFailed,
Expand Down
7 changes: 4 additions & 3 deletions src/memory/pressure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fs::File;
use std::io::Read;

use crate::error::{Error, Result};
use crate::utils::str_from_u8;
use crate::utils::str_from_bytes;

macro_rules! malformed {
() => {
Expand All @@ -22,8 +22,9 @@ pub fn pressure_some_avg10(buf: &mut [u8]) -> Result<f32> {

// `buf` won't be large enough to fit all of `/proc/pressure/memory`
// but will be large enough to hold at least the first line, which has the data we want
let _ = file.read(buf)?;
let contents = str_from_u8(buf)?;
file.read(buf)?;
let contents = str_from_bytes(buf)?;

let line = contents.lines().next().ok_or(malformed!())?;
let mut words = line.split_ascii_whitespace();
if let Some(indicator) = words.next() {
Expand Down
10 changes: 5 additions & 5 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use libc::getpgid;
use crate::checked_ffi;
use crate::{
error::{Error, Result},
utils::{self, str_from_u8},
utils::{self, str_from_bytes},
};

#[derive(Debug, Default)]
Expand Down Expand Up @@ -53,7 +53,7 @@ impl Process {
let _ = file.read(buf)?;
}

str_from_u8(buf)
str_from_bytes(buf)
}

pub fn oom_score_from_pid(pid: u32, buf: &mut [u8]) -> Result<i16> {
Expand All @@ -63,7 +63,7 @@ impl Process {
buf.fill(0);
let _ = file.read(buf)?;

str_from_u8(buf)?.trim()
str_from_bytes(buf)?.trim()
};

Ok(contents.parse()?)
Expand All @@ -80,7 +80,7 @@ impl Process {
buf.fill(0);
let _ = file.read(buf)?;

str_from_u8(buf)?.split_ascii_whitespace()
str_from_bytes(buf)?.split_ascii_whitespace()
};
let vm_rss: i64 = columns.nth(1).ok_or(Error::MalformedStatm)?.parse()?;

Expand Down Expand Up @@ -115,7 +115,7 @@ impl Process {
buf.fill(0);
let _ = file.read(buf)?;

str_from_u8(buf)?.trim()
str_from_bytes(buf)?.trim()
};

Ok(contents.parse()?)
Expand Down
9 changes: 4 additions & 5 deletions src/uname.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::mem;
use crate::checked_ffi;
use crate::error::{Error, Result};
use crate::linux_version::LinuxVersion;
use crate::utils::str_from_u8;
use libc::{uname, utsname};

pub struct Uname {
Expand Down Expand Up @@ -35,10 +34,10 @@ impl Uname {
let release = unsafe { CStr::from_ptr(self.uts_struct.release.as_ptr()) };
let arch = unsafe { CStr::from_ptr(self.uts_struct.machine.as_ptr()) };

let sysname = str_from_u8(sysname.to_bytes())?;
let hostname = str_from_u8(hostname.to_bytes())?;
let release = str_from_u8(release.to_bytes())?;
let arch = str_from_u8(arch.to_bytes())?;
let sysname = sysname.to_str()?;
let hostname = hostname.to_str()?;
let release = release.to_str()?;
let arch = arch.to_str()?;

println!("OS: {}", sysname);
println!("Hostname: {}", hostname);
Expand Down
29 changes: 21 additions & 8 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::ffi::OsStr;
use std::fs::File;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
use std::{ffi::CStr, mem, ptr, str};

use libc::_SC_PAGESIZE;
Expand Down Expand Up @@ -83,18 +86,28 @@ pub fn get_username() -> Option<String> {
None
}

/// Construct a string slice ranging from the first position to the position of the first nul byte
pub fn str_from_u8(buf: &[u8]) -> Result<&str> {
let first_nul_idx = memchr(b'0', buf).unwrap_or(buf.len());
fn bytes_until_first_nil(buf: &[u8]) -> &[u8] {
let first_nul_idx = memchr(0, buf).unwrap_or(buf.len());

&buf[0..first_nul_idx]
}

let bytes = buf.get(0..first_nul_idx).ok_or(Error::StringFromBytes)?;
/// Construct a string slice ranging from the first position to the position of the first nul byte
pub fn str_from_bytes(buf: &[u8]) -> Result<&str> {
let bytes = bytes_until_first_nil(buf);

Ok(str::from_utf8(bytes)?)
}

fn path_from_bytes(buf: &[u8]) -> &Path {
let bytes = bytes_until_first_nil(buf);

Path::new(OsStr::from_bytes(bytes))
}

/// Given a slice of bytes, try to interpret it as a file path and open the corresponding file.
pub fn file_from_buffer(buf: &[u8]) -> Result<File> {
let path = str_from_u8(buf)?;
let path = path_from_bytes(buf);
let file = File::open(path)?;
Ok(file)
}
Expand All @@ -106,11 +119,11 @@ pub fn bytes_to_megabytes(bytes: impl Into<u64>, mem_unit: impl Into<u64>) -> u6

#[cfg(test)]
mod tests {
use super::str_from_u8;
use super::str_from_bytes;

#[test]
fn should_construct_string_slice_from_bytes() {
assert_eq!(str_from_u8(b"ABC\0").unwrap(), "ABC");
assert_eq!(str_from_u8(b"ABC\0abc").unwrap(), "ABC");
assert_eq!(str_from_bytes(b"ABC\0").unwrap(), "ABC");
assert_eq!(str_from_bytes(b"ABC\0abc").unwrap(), "ABC");
}
}

0 comments on commit fab04c5

Please sign in to comment.