Rust 1.85, edition=2024 (#15741)

This commit is contained in:
Jack Wright
2025-05-13 07:49:30 -07:00
committed by GitHub
parent 1a0986903f
commit c2ac8f730e
793 changed files with 4276 additions and 3687 deletions

View File

@ -4,7 +4,7 @@ description = "Nushell system querying"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-system"
name = "nu-system"
version = "0.104.1"
edition = "2021"
edition = "2024"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -48,4 +48,4 @@ windows = { workspace = true, features = [
"Win32_System_SystemInformation",
"Win32_System_Threading",
"Win32_UI_Shell",
]}
]}

View File

@ -1,4 +1,4 @@
use std::sync::{atomic::AtomicU32, Arc};
use std::sync::{Arc, atomic::AtomicU32};
use std::io;
@ -274,11 +274,7 @@ impl ForegroundGuard {
} else if pcnt
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |count| {
// Avoid a race condition: only increment if count is > 0
if count > 0 {
Some(count + 1)
} else {
None
}
if count > 0 { Some(count + 1) } else { None }
})
.is_ok()
{
@ -349,7 +345,7 @@ impl Drop for ForegroundGuard {
#[cfg(unix)]
mod child_pgroup {
use nix::{
sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal},
sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction},
unistd::{self, Pid},
};
use std::{

View File

@ -1,7 +1,7 @@
use itertools::{EitherOrBoth, Itertools};
use libc::{
c_char, kinfo_proc, sysctl, CTL_HW, CTL_KERN, KERN_PROC, KERN_PROC_ALL, KERN_PROC_ARGS,
TDF_IDLETD,
CTL_HW, CTL_KERN, KERN_PROC, KERN_PROC_ALL, KERN_PROC_ARGS, TDF_IDLETD, c_char, kinfo_proc,
sysctl,
};
use std::{
ffi::CStr,

View File

@ -97,7 +97,9 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
let curr_proc = if let Ok(p) = Process::new(curr_proc_pid) {
p
} else {
info!("failed to retrieve info for pid={curr_proc_pid}, process probably died between snapshots");
info!(
"failed to retrieve info for pid={curr_proc_pid}, process probably died between snapshots"
);
continue;
};
let cwd = curr_proc.cwd().unwrap_or_default();

View File

@ -1,12 +1,12 @@
use libc::{c_int, c_void, size_t};
use libproc::libproc::bsd_info::BSDInfo;
use libproc::libproc::file_info::{pidfdinfo, ListFDs, ProcFDType};
use libproc::libproc::file_info::{ListFDs, ProcFDType, pidfdinfo};
use libproc::libproc::net_info::{InSockInfo, SocketFDInfo, SocketInfoKind, TcpSockInfo};
use libproc::libproc::pid_rusage::{pidrusage, RUsageInfoV2};
use libproc::libproc::proc_pid::{listpidinfo, pidinfo, ListThreads};
use libproc::libproc::pid_rusage::{RUsageInfoV2, pidrusage};
use libproc::libproc::proc_pid::{ListThreads, listpidinfo, pidinfo};
use libproc::libproc::task_info::{TaskAllInfo, TaskInfo};
use libproc::libproc::thread_info::ThreadInfo;
use libproc::processes::{pids_by_type, ProcFilter};
use libproc::processes::{ProcFilter, pids_by_type};
use mach2::mach_time;
use std::cmp;
use std::path::{Path, PathBuf};
@ -155,9 +155,11 @@ pub struct PathInfo {
}
unsafe fn get_unchecked_str(cp: *mut u8, start: *mut u8) -> String {
let len = (cp as usize).saturating_sub(start as usize);
let part = std::slice::from_raw_parts(start, len);
String::from_utf8_unchecked(part.to_vec())
unsafe {
let len = (cp as usize).saturating_sub(start as usize);
let part = std::slice::from_raw_parts(start, len);
String::from_utf8_unchecked(part.to_vec())
}
}
fn get_path_info(pid: i32, mut size: size_t) -> Option<PathInfo> {

View File

@ -1,7 +1,7 @@
//! This is used for both NetBSD and OpenBSD, because they are fairly similar.
use itertools::{EitherOrBoth, Itertools};
use libc::{sysctl, CTL_HW, CTL_KERN, KERN_PROC_ALL, KERN_PROC_ARGS, KERN_PROC_ARGV};
use libc::{CTL_HW, CTL_KERN, KERN_PROC_ALL, KERN_PROC_ARGS, KERN_PROC_ARGV, sysctl};
use std::{
io,
mem::{self, MaybeUninit},

View File

@ -11,7 +11,7 @@ use ntapi::ntwow64::{PEB32, RTL_USER_PROCESS_PARAMETERS32};
use std::cell::RefCell;
use std::collections::HashMap;
use std::ffi::OsString;
use std::mem::{size_of, zeroed, MaybeUninit};
use std::mem::{MaybeUninit, size_of, zeroed};
use std::os::windows::ffi::OsStringExt;
use std::path::PathBuf;
use std::ptr;
@ -25,27 +25,27 @@ use windows::core::{PCWSTR, PWSTR};
use windows::Wdk::System::SystemServices::RtlGetVersion;
use windows::Wdk::System::Threading::{
NtQueryInformationProcess, ProcessBasicInformation, ProcessCommandLineInformation,
ProcessWow64Information, PROCESSINFOCLASS,
NtQueryInformationProcess, PROCESSINFOCLASS, ProcessBasicInformation,
ProcessCommandLineInformation, ProcessWow64Information,
};
use windows::Win32::Foundation::{
CloseHandle, LocalFree, FALSE, FILETIME, HANDLE, HLOCAL, HMODULE, MAX_PATH, PSID,
CloseHandle, FALSE, FILETIME, HANDLE, HLOCAL, HMODULE, LocalFree, MAX_PATH, PSID,
STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH, UNICODE_STRING,
};
use windows::Win32::Security::{
AdjustTokenPrivileges, GetTokenInformation, LookupAccountSidW, LookupPrivilegeValueW,
TokenGroups, TokenUser, SE_DEBUG_NAME, SE_PRIVILEGE_ENABLED, SID, SID_NAME_USE,
TOKEN_ADJUST_PRIVILEGES, TOKEN_GROUPS, TOKEN_PRIVILEGES, TOKEN_QUERY, TOKEN_USER,
SE_DEBUG_NAME, SE_PRIVILEGE_ENABLED, SID, SID_NAME_USE, TOKEN_ADJUST_PRIVILEGES, TOKEN_GROUPS,
TOKEN_PRIVILEGES, TOKEN_QUERY, TOKEN_USER, TokenGroups, TokenUser,
};
use windows::Win32::System::Diagnostics::Debug::ReadProcessMemory;
use windows::Win32::System::Diagnostics::ToolHelp::{
CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS,
CreateToolhelp32Snapshot, PROCESSENTRY32, Process32First, Process32Next, TH32CS_SNAPPROCESS,
};
use windows::Win32::System::Memory::{VirtualQueryEx, MEMORY_BASIC_INFORMATION};
use windows::Win32::System::Memory::{MEMORY_BASIC_INFORMATION, VirtualQueryEx};
use windows::Win32::System::ProcessStatus::{
GetModuleBaseNameW, GetProcessMemoryInfo, K32EnumProcesses, PROCESS_MEMORY_COUNTERS,
@ -55,8 +55,8 @@ use windows::Win32::System::ProcessStatus::{
use windows::Win32::System::SystemInformation::OSVERSIONINFOEXW;
use windows::Win32::System::Threading::{
GetCurrentProcess, GetPriorityClass, GetProcessIoCounters, GetProcessTimes, OpenProcess,
OpenProcessToken, IO_COUNTERS, PEB, PROCESS_BASIC_INFORMATION, PROCESS_QUERY_INFORMATION,
GetCurrentProcess, GetPriorityClass, GetProcessIoCounters, GetProcessTimes, IO_COUNTERS,
OpenProcess, OpenProcessToken, PEB, PROCESS_BASIC_INFORMATION, PROCESS_QUERY_INFORMATION,
PROCESS_VM_READ,
};
@ -364,10 +364,10 @@ fn get_times(handle: HANDLE) -> Option<(u64, u64, u64, u64)> {
&mut user as *mut FILETIME,
);
let start = u64::from(start.dwHighDateTime) << 32 | u64::from(start.dwLowDateTime);
let exit = u64::from(exit.dwHighDateTime) << 32 | u64::from(exit.dwLowDateTime);
let sys = u64::from(sys.dwHighDateTime) << 32 | u64::from(sys.dwLowDateTime);
let user = u64::from(user.dwHighDateTime) << 32 | u64::from(user.dwLowDateTime);
let start = (u64::from(start.dwHighDateTime) << 32) | u64::from(start.dwLowDateTime);
let exit = (u64::from(exit.dwHighDateTime) << 32) | u64::from(exit.dwLowDateTime);
let sys = (u64::from(sys.dwHighDateTime) << 32) | u64::from(sys.dwLowDateTime);
let user = (u64::from(user.dwHighDateTime) << 32) | u64::from(user.dwLowDateTime);
if ret.is_ok() {
Some((start, exit, sys, user))
@ -480,217 +480,227 @@ unsafe fn get_process_data(
let mut buffer: Vec<u16> = Vec::with_capacity(size / 2 + 1);
let mut bytes_read = 0;
if ReadProcessMemory(
handle,
ptr,
buffer.as_mut_ptr().cast(),
size,
Some(&mut bytes_read),
)
.is_err()
{
return Err("Unable to read process data");
}
unsafe {
if ReadProcessMemory(
handle,
ptr,
buffer.as_mut_ptr().cast(),
size,
Some(&mut bytes_read),
)
.is_err()
{
return Err("Unable to read process data");
}
// Documentation states that the function fails if not all data is accessible.
if bytes_read != size {
return Err("ReadProcessMemory returned unexpected number of bytes read");
}
// Documentation states that the function fails if not all data is accessible.
if bytes_read != size {
return Err("ReadProcessMemory returned unexpected number of bytes read");
}
buffer.set_len(size / 2);
buffer.push(0);
buffer.set_len(size / 2);
buffer.push(0);
}
Ok(buffer)
}
unsafe fn get_region_size(handle: HANDLE, ptr: *const c_void) -> Result<usize, &'static str> {
let mut meminfo = MaybeUninit::<MEMORY_BASIC_INFORMATION>::uninit();
if VirtualQueryEx(
handle,
Some(ptr),
meminfo.as_mut_ptr().cast(),
size_of::<MEMORY_BASIC_INFORMATION>(),
) == 0
{
return Err("Unable to read process memory information");
unsafe {
let mut meminfo = MaybeUninit::<MEMORY_BASIC_INFORMATION>::uninit();
if VirtualQueryEx(
handle,
Some(ptr),
meminfo.as_mut_ptr().cast(),
size_of::<MEMORY_BASIC_INFORMATION>(),
) == 0
{
return Err("Unable to read process memory information");
}
let meminfo = meminfo.assume_init();
Ok((meminfo.RegionSize as isize - ptr.offset_from(meminfo.BaseAddress)) as usize)
}
let meminfo = meminfo.assume_init();
Ok((meminfo.RegionSize as isize - ptr.offset_from(meminfo.BaseAddress)) as usize)
}
unsafe fn ph_query_process_variable_size(
process_handle: HANDLE,
process_information_class: PROCESSINFOCLASS,
) -> Option<Vec<u16>> {
let mut return_length = MaybeUninit::<u32>::uninit();
unsafe {
let mut return_length = MaybeUninit::<u32>::uninit();
if let Err(err) = NtQueryInformationProcess(
process_handle,
process_information_class,
std::ptr::null_mut(),
0,
return_length.as_mut_ptr() as *mut _,
)
.ok()
{
if ![
STATUS_BUFFER_OVERFLOW.into(),
STATUS_BUFFER_TOO_SMALL.into(),
STATUS_INFO_LENGTH_MISMATCH.into(),
]
.contains(&err.code())
if let Err(err) = NtQueryInformationProcess(
process_handle,
process_information_class,
std::ptr::null_mut(),
0,
return_length.as_mut_ptr() as *mut _,
)
.ok()
{
if ![
STATUS_BUFFER_OVERFLOW.into(),
STATUS_BUFFER_TOO_SMALL.into(),
STATUS_INFO_LENGTH_MISMATCH.into(),
]
.contains(&err.code())
{
return None;
}
}
let mut return_length = return_length.assume_init();
let buf_len = (return_length as usize) / 2;
let mut buffer: Vec<u16> = Vec::with_capacity(buf_len + 1);
if NtQueryInformationProcess(
process_handle,
process_information_class,
buffer.as_mut_ptr() as *mut _,
return_length,
&mut return_length as *mut _,
)
.is_err()
{
return None;
}
buffer.set_len(buf_len);
buffer.push(0);
Some(buffer)
}
let mut return_length = return_length.assume_init();
let buf_len = (return_length as usize) / 2;
let mut buffer: Vec<u16> = Vec::with_capacity(buf_len + 1);
if NtQueryInformationProcess(
process_handle,
process_information_class,
buffer.as_mut_ptr() as *mut _,
return_length,
&mut return_length as *mut _,
)
.is_err()
{
return None;
}
buffer.set_len(buf_len);
buffer.push(0);
Some(buffer)
}
unsafe fn get_cmdline_from_buffer(buffer: PCWSTR) -> Vec<String> {
// Get argc and argv from the command line
let mut argc = MaybeUninit::<i32>::uninit();
let argv_p = CommandLineToArgvW(buffer, argc.as_mut_ptr());
if argv_p.is_null() {
return Vec::new();
unsafe {
// Get argc and argv from the command line
let mut argc = MaybeUninit::<i32>::uninit();
let argv_p = CommandLineToArgvW(buffer, argc.as_mut_ptr());
if argv_p.is_null() {
return Vec::new();
}
let argc = argc.assume_init();
let argv = std::slice::from_raw_parts(argv_p, argc as usize);
let mut res = Vec::new();
for arg in argv {
res.push(String::from_utf16_lossy(arg.as_wide()));
}
let _err = LocalFree(HLOCAL(argv_p as _));
res
}
let argc = argc.assume_init();
let argv = std::slice::from_raw_parts(argv_p, argc as usize);
let mut res = Vec::new();
for arg in argv {
res.push(String::from_utf16_lossy(arg.as_wide()));
}
let _err = LocalFree(HLOCAL(argv_p as _));
res
}
unsafe fn get_process_params(
handle: HANDLE,
) -> Result<(Vec<String>, Vec<String>, PathBuf), &'static str> {
if !cfg!(target_pointer_width = "64") {
return Err("Non 64 bit targets are not supported");
}
unsafe {
if !cfg!(target_pointer_width = "64") {
return Err("Non 64 bit targets are not supported");
}
// First check if target process is running in wow64 compatibility emulator
let mut pwow32info = MaybeUninit::<*const c_void>::uninit();
if NtQueryInformationProcess(
handle,
ProcessWow64Information,
pwow32info.as_mut_ptr().cast(),
size_of::<*const c_void>() as u32,
null_mut(),
)
.is_err()
{
return Err("Unable to check WOW64 information about the process");
}
let pwow32info = pwow32info.assume_init();
if pwow32info.is_null() {
// target is a 64 bit process
let mut pbasicinfo = MaybeUninit::<PROCESS_BASIC_INFORMATION>::uninit();
// First check if target process is running in wow64 compatibility emulator
let mut pwow32info = MaybeUninit::<*const c_void>::uninit();
if NtQueryInformationProcess(
handle,
ProcessBasicInformation,
pbasicinfo.as_mut_ptr().cast(),
size_of::<PROCESS_BASIC_INFORMATION>() as u32,
ProcessWow64Information,
pwow32info.as_mut_ptr().cast(),
size_of::<*const c_void>() as u32,
null_mut(),
)
.is_err()
{
return Err("Unable to get basic process information");
return Err("Unable to check WOW64 information about the process");
}
let pinfo = pbasicinfo.assume_init();
let pwow32info = pwow32info.assume_init();
let mut peb = MaybeUninit::<PEB>::uninit();
if pwow32info.is_null() {
// target is a 64 bit process
let mut pbasicinfo = MaybeUninit::<PROCESS_BASIC_INFORMATION>::uninit();
if NtQueryInformationProcess(
handle,
ProcessBasicInformation,
pbasicinfo.as_mut_ptr().cast(),
size_of::<PROCESS_BASIC_INFORMATION>() as u32,
null_mut(),
)
.is_err()
{
return Err("Unable to get basic process information");
}
let pinfo = pbasicinfo.assume_init();
let mut peb = MaybeUninit::<PEB>::uninit();
if ReadProcessMemory(
handle,
pinfo.PebBaseAddress.cast(),
peb.as_mut_ptr().cast(),
size_of::<PEB>(),
None,
)
.is_err()
{
return Err("Unable to read process PEB");
}
let peb = peb.assume_init();
let mut proc_params = MaybeUninit::<RTL_USER_PROCESS_PARAMETERS>::uninit();
if ReadProcessMemory(
handle,
peb.ProcessParameters.cast(),
proc_params.as_mut_ptr().cast(),
size_of::<RTL_USER_PROCESS_PARAMETERS>(),
None,
)
.is_err()
{
return Err("Unable to read process parameters");
}
let proc_params = proc_params.assume_init();
return Ok((
get_cmd_line(&proc_params, handle),
get_proc_env(&proc_params, handle),
get_cwd(&proc_params, handle),
));
}
// target is a 32 bit process in wow64 mode
let mut peb32 = MaybeUninit::<PEB32>::uninit();
if ReadProcessMemory(
handle,
pinfo.PebBaseAddress.cast(),
peb.as_mut_ptr().cast(),
size_of::<PEB>(),
pwow32info,
peb32.as_mut_ptr().cast(),
size_of::<PEB32>(),
None,
)
.is_err()
{
return Err("Unable to read process PEB");
return Err("Unable to read PEB32");
}
let peb32 = peb32.assume_init();
let peb = peb.assume_init();
let mut proc_params = MaybeUninit::<RTL_USER_PROCESS_PARAMETERS>::uninit();
let mut proc_params = MaybeUninit::<RTL_USER_PROCESS_PARAMETERS32>::uninit();
if ReadProcessMemory(
handle,
peb.ProcessParameters.cast(),
peb32.ProcessParameters as *mut _,
proc_params.as_mut_ptr().cast(),
size_of::<RTL_USER_PROCESS_PARAMETERS>(),
size_of::<RTL_USER_PROCESS_PARAMETERS32>(),
None,
)
.is_err()
{
return Err("Unable to read process parameters");
return Err("Unable to read 32 bit process parameters");
}
let proc_params = proc_params.assume_init();
return Ok((
Ok((
get_cmd_line(&proc_params, handle),
get_proc_env(&proc_params, handle),
get_cwd(&proc_params, handle),
));
))
}
// target is a 32 bit process in wow64 mode
let mut peb32 = MaybeUninit::<PEB32>::uninit();
if ReadProcessMemory(
handle,
pwow32info,
peb32.as_mut_ptr().cast(),
size_of::<PEB32>(),
None,
)
.is_err()
{
return Err("Unable to read PEB32");
}
let peb32 = peb32.assume_init();
let mut proc_params = MaybeUninit::<RTL_USER_PROCESS_PARAMETERS32>::uninit();
if ReadProcessMemory(
handle,
peb32.ProcessParameters as *mut _,
proc_params.as_mut_ptr().cast(),
size_of::<RTL_USER_PROCESS_PARAMETERS32>(),
None,
)
.is_err()
{
return Err("Unable to read 32 bit process parameters");
}
let proc_params = proc_params.assume_init();
Ok((
get_cmd_line(&proc_params, handle),
get_proc_env(&proc_params, handle),
get_cwd(&proc_params, handle),
))
}
static WINDOWS_8_1_OR_NEWER: LazyLock<bool> = LazyLock::new(|| unsafe {