Skip to content

Commit

Permalink
Merge pull request #1242 from GuillaumeGomez/backport
Browse files Browse the repository at this point in the history
Backport #1239 and #1241 to 0.30
  • Loading branch information
GuillaumeGomez committed Apr 8, 2024
2 parents fe30f16 + 663a429 commit 5572687
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 223 deletions.
2 changes: 1 addition & 1 deletion src/common.rs
Expand Up @@ -1624,7 +1624,7 @@ impl UpdateKind {
///
/// When all refresh are ruled out, a [`Process`] will still retrieve the following information:
/// * Process ID ([`Pid`])
/// * Parent process ID
/// * Parent process ID (on Windows it never changes though)
/// * Process name
/// * Start time
///
Expand Down
18 changes: 14 additions & 4 deletions src/unix/apple/macos/process.rs
Expand Up @@ -335,6 +335,13 @@ unsafe fn get_bsd_info(pid: Pid) -> Option<libc::proc_bsdinfo> {
}
}

fn get_parent(info: &libc::proc_bsdinfo) -> Option<Pid> {
match info.pbi_ppid as i32 {
0 => None,
p => Some(Pid(p)),
}
}

unsafe fn create_new_process(
pid: Pid,
now: u64,
Expand All @@ -353,10 +360,8 @@ unsafe fn create_new_process(
return Err(());
}
};
let parent = match info.pbi_ppid as i32 {
0 => None,
p => Some(Pid(p)),
};

let parent = get_parent(&info);

let start_time = info.pbi_start_tvsec;
let run_time = now.saturating_sub(start_time);
Expand Down Expand Up @@ -654,6 +659,11 @@ pub(crate) fn update_process(
// The owner of this PID changed.
return create_new_process(pid, now, refresh_kind, Some(info));
}
let parent = get_parent(&info);
// Update the parent if it changed.
if p.parent != parent {
p.parent = parent;
}
}

if !get_process_infos(p, refresh_kind) {
Expand Down
14 changes: 12 additions & 2 deletions src/unix/linux/component.rs
Expand Up @@ -240,9 +240,16 @@ impl ComponentInner {
let dir = read_dir(folder).ok()?;
let mut matchings: HashMap<u32, Component> = HashMap::with_capacity(10);
for entry in dir.flatten() {
let Ok(file_type) = entry.file_type() else {
continue;
};
if file_type.is_dir() {
continue;
}

let entry = entry.path();
let filename = entry.file_name().and_then(|x| x.to_str()).unwrap_or("");
if entry.is_dir() || !filename.starts_with("temp") {
if !filename.starts_with("temp") {
continue;
}

Expand Down Expand Up @@ -363,8 +370,11 @@ impl ComponentsInner {
self.components.clear();
if let Ok(dir) = read_dir(Path::new("/sys/class/hwmon/")) {
for entry in dir.flatten() {
let Ok(file_type) = entry.file_type() else {
continue;
};
let entry = entry.path();
if !entry.is_dir()
if !file_type.is_dir()
|| !entry
.file_name()
.and_then(|x| x.to_str())
Expand Down
2 changes: 1 addition & 1 deletion src/unix/linux/network.rs
@@ -1,9 +1,9 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use std::collections::{hash_map, HashMap};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::{fs::File, u8};

use crate::common::MacAddr;
use crate::network::refresh_networks_addresses;
Expand Down
67 changes: 46 additions & 21 deletions src/unix/linux/process.rs
Expand Up @@ -396,12 +396,15 @@ fn refresh_user_group_ids(
#[allow(clippy::too_many_arguments)]
fn update_proc_info(
p: &mut ProcessInner,
parent_pid: Option<Pid>,
refresh_kind: ProcessRefreshKind,
proc_path: &mut PathHandler,
parts: &[&str],
uptime: u64,
info: &SystemInfo,
) {
update_parent_pid(p, parent_pid, parts);

get_status(p, parts[ProcIndex::State as usize]);
refresh_user_group_ids(p, proc_path, refresh_kind);

Expand Down Expand Up @@ -430,6 +433,16 @@ fn update_proc_info(
}
}

fn update_parent_pid(p: &mut ProcessInner, parent_pid: Option<Pid>, str_parts: &[&str]) {
p.parent = match parent_pid {
Some(parent_pid) if parent_pid.0 != 0 => Some(parent_pid),
_ => match Pid::from_str(str_parts[ProcIndex::ParentPid as usize]) {
Ok(p) if p.0 != 0 => Some(p),
_ => None,
},
};
}

fn retrieve_all_new_process_info(
pid: Pid,
parent_pid: Option<Pid>,
Expand All @@ -443,14 +456,6 @@ fn retrieve_all_new_process_info(
let mut proc_path = PathHandler::new(path);
let name = parts[ProcIndex::ShortExe as usize];

p.parent = match parent_pid {
Some(parent_pid) if parent_pid.0 != 0 => Some(parent_pid),
_ => match Pid::from_str(parts[ProcIndex::ParentPid as usize]) {
Ok(p) if p.0 != 0 => Some(p),
_ => None,
},
};

p.start_time_without_boot_time = compute_start_time_without_boot_time(parts, info);
p.start_time = p
.start_time_without_boot_time
Expand All @@ -466,7 +471,15 @@ fn retrieve_all_new_process_info(
p.thread_kind = Some(ThreadKind::Userland);
}

update_proc_info(&mut p, refresh_kind, &mut proc_path, parts, uptime, info);
update_proc_info(
&mut p,
parent_pid,
refresh_kind,
&mut proc_path,
parts,
uptime,
info,
);

Process { inner: p }
}
Expand Down Expand Up @@ -508,7 +521,15 @@ pub(crate) fn _get_process_data(
if start_time_without_boot_time == entry.start_time_without_boot_time {
let mut proc_path = PathHandler::new(path);

update_proc_info(entry, refresh_kind, &mut proc_path, &parts, uptime, info);
update_proc_info(
entry,
parent_pid,
refresh_kind,
&mut proc_path,
&parts,
uptime,
info,
);

refresh_user_group_ids(entry, &mut proc_path, refresh_kind);
return Ok((None, pid));
Expand Down Expand Up @@ -636,6 +657,13 @@ fn get_all_pid_entries(
entry: DirEntry,
data: &mut Vec<ProcAndTasks>,
) -> Option<Pid> {
let Ok(file_type) = entry.file_type() else {
return None;
};
if !file_type.is_dir() {
return None;
}

let entry = entry.path();
let name = entry.file_name();

Expand All @@ -644,26 +672,23 @@ fn get_all_pid_entries(
return None;
}
let name = name?;
if !entry.is_dir() {
return None;
}
let pid = Pid::from(usize::from_str(&name.to_string_lossy()).ok()?);

let tasks_dir = Path::join(&entry, "task");
let tasks = if tasks_dir.is_dir() {

let tasks = if let Ok(entries) = fs::read_dir(tasks_dir) {
let mut tasks = HashSet::new();
if let Ok(entries) = fs::read_dir(tasks_dir) {
for task in entries
.into_iter()
.filter_map(|entry| get_all_pid_entries(Some(name), Some(pid), entry.ok()?, data))
{
tasks.insert(task);
}
for task in entries
.into_iter()
.filter_map(|entry| get_all_pid_entries(Some(name), Some(pid), entry.ok()?, data))
{
tasks.insert(task);
}
Some(tasks)
} else {
None
};

data.push(ProcAndTasks {
pid,
parent_pid,
Expand Down
36 changes: 6 additions & 30 deletions src/windows/disk.rs
@@ -1,5 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::sys::utils::HandleWrapper;
use crate::{Disk, DiskKind};

use std::ffi::{c_void, OsStr, OsString};
Expand All @@ -8,11 +9,10 @@ use std::os::windows::ffi::OsStringExt;
use std::path::Path;

use windows::core::{Error, HRESULT, PCWSTR};
use windows::Win32::Foundation::{CloseHandle, HANDLE, MAX_PATH};
use windows::Win32::Foundation::MAX_PATH;
use windows::Win32::Storage::FileSystem::{
CreateFileW, FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetDiskFreeSpaceExW,
GetDriveTypeW, GetVolumeInformationW, GetVolumePathNamesForVolumeNameW, FILE_ACCESS_RIGHTS,
FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING,
FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetDiskFreeSpaceExW, GetDriveTypeW,
GetVolumeInformationW, GetVolumePathNamesForVolumeNameW,
};
use windows::Win32::System::Ioctl::{
PropertyStandardQuery, StorageDeviceSeekPenaltyProperty, DEVICE_SEEK_PENALTY_DESCRIPTOR,
Expand Down Expand Up @@ -205,31 +205,6 @@ impl DisksInner {
}
}

struct HandleWrapper(HANDLE);

impl HandleWrapper {
unsafe fn new(drive_name: &[u16], open_rights: FILE_ACCESS_RIGHTS) -> Option<Self> {
let lpfilename = PCWSTR::from_raw(drive_name.as_ptr());
let handle = CreateFileW(
lpfilename,
open_rights.0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
None,
OPEN_EXISTING,
Default::default(),
HANDLE::default(),
)
.ok()?;
Some(Self(handle))
}
}

impl Drop for HandleWrapper {
fn drop(&mut self) {
let _err = unsafe { CloseHandle(self.0) };
}
}

unsafe fn get_drive_size(mount_point: &[u16]) -> Option<(u64, u64)> {
let mut total_size = 0;
let mut available_space = 0;
Expand Down Expand Up @@ -292,7 +267,8 @@ pub(crate) unsafe fn get_list() -> Vec<Disk> {
.copied()
.chain([0])
.collect::<Vec<_>>();
let Some(handle) = HandleWrapper::new(&device_path[..], Default::default()) else {
let Some(handle) = HandleWrapper::new_from_file(&device_path[..], Default::default())
else {
return Vec::new();
};
let Some((total_space, available_space)) = get_drive_size(&mount_paths[0][..]) else {
Expand Down

0 comments on commit 5572687

Please sign in to comment.