mirror of
https://github.com/uutils/procps.git
synced 2026-06-10 16:14:00 -07:00
pgrep: remove libc in pgrep
Use rustix instead of libc and unsafe functions such as getpgrp, getsid, flock, gettid, getppid, getpgid, and getsid.
This commit is contained in:
@@ -16,7 +16,7 @@ workspace = true
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
rustix = { workspace = true }
|
||||
rustix = { workspace = true, features = ["fs", "process", "thread"] }
|
||||
uucore = { workspace = true, features = ["entries", "signals", "process"] }
|
||||
walkdir = { workspace = true }
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ impl Teletype {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn from_tty_nr_impl(tty_nr: u64, drivers: &[TtyDriverEntry]) -> Self {
|
||||
use uucore::libc::{major, minor};
|
||||
use rustix::fs::{major, minor};
|
||||
|
||||
if tty_nr == 0 {
|
||||
return Self::Unknown;
|
||||
@@ -843,7 +843,7 @@ unknown /dev/tty 4 1-63 console"#;
|
||||
];
|
||||
|
||||
for (major, minor, expected) in test_cases {
|
||||
let tty_nr = uucore::libc::makedev(major, minor);
|
||||
let tty_nr = rustix::fs::makedev(major, minor);
|
||||
let result = Teletype::from_tty_nr_impl(tty_nr, &parsed_entries);
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
@@ -904,14 +904,14 @@ unknown /dev/tty 4 1-63 console"#;
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_thread_ids() {
|
||||
let main_tid = unsafe { uucore::libc::gettid() };
|
||||
let main_tid = rustix::thread::gettid().as_raw_nonzero().get() as u64;
|
||||
std::thread::spawn(move || {
|
||||
let mut pid_entry = ProcessInformation::current_process_info().unwrap();
|
||||
let thread_ids = pid_entry.thread_ids();
|
||||
|
||||
assert!(thread_ids.contains(&(main_tid as usize)));
|
||||
|
||||
let new_thread_tid = unsafe { uucore::libc::gettid() };
|
||||
let new_thread_tid = rustix::thread::gettid().as_raw_nonzero().get() as u64;
|
||||
assert!(thread_ids.contains(&(new_thread_tid as usize)));
|
||||
})
|
||||
.join()
|
||||
@@ -939,14 +939,24 @@ unknown /dev/tty 4 1-63 console"#;
|
||||
let mut pid_entry = ProcessInformation::current_process_info().unwrap();
|
||||
assert_eq!(
|
||||
pid_entry.ppid().unwrap(),
|
||||
unsafe { uucore::libc::getppid() } as u64
|
||||
rustix::process::getppid()
|
||||
.map(|pid| pid.as_raw_nonzero().get() as u64)
|
||||
.unwrap_or(0)
|
||||
);
|
||||
assert_eq!(
|
||||
pid_entry.pgid().unwrap(),
|
||||
unsafe { uucore::libc::getpgid(0) } as u64
|
||||
rustix::process::getpgid(None)
|
||||
.ok()
|
||||
.map(|pid| pid.as_raw_nonzero().get() as u64)
|
||||
.unwrap_or(0)
|
||||
);
|
||||
assert_eq!(
|
||||
pid_entry.sid().unwrap(),
|
||||
rustix::process::getsid(None)
|
||||
.ok()
|
||||
.map(|pid| pid.as_raw_nonzero().get() as u64)
|
||||
.unwrap_or(0)
|
||||
);
|
||||
assert_eq!(pid_entry.sid().unwrap(), unsafe { uucore::libc::getsid(0) }
|
||||
as u64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -6,15 +6,11 @@
|
||||
// Common process matcher logic shared by pgrep, pkill and pidwait
|
||||
|
||||
use std::hash::Hash;
|
||||
#[cfg(unix)]
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::{collections::HashSet, io};
|
||||
|
||||
use clap::{arg, Arg, ArgAction, ArgMatches};
|
||||
use regex::Regex;
|
||||
#[cfg(unix)]
|
||||
use uucore::libc::{getpgrp, getsid};
|
||||
#[cfg(unix)]
|
||||
use uucore::{
|
||||
display::Quotable,
|
||||
entries::{grp2gid, usr2uid},
|
||||
@@ -91,24 +87,12 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
|
||||
.get_many::<u32>("group")
|
||||
.map(|ids| ids.cloned().collect()),
|
||||
pgroup: matches.get_many::<u64>("pgroup").map(|xs| {
|
||||
xs.map(|pg| {
|
||||
if *pg == 0 {
|
||||
unsafe { getpgrp() as u64 }
|
||||
} else {
|
||||
*pg
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
xs.map(|pg| if *pg == 0 { getpgrp() } else { *pg })
|
||||
.collect()
|
||||
}),
|
||||
session: matches.get_many::<u64>("session").map(|xs| {
|
||||
xs.map(|sid| {
|
||||
if *sid == 0 {
|
||||
unsafe { getsid(0) as u64 }
|
||||
} else {
|
||||
*sid
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
xs.map(|sid| if *sid == 0 { getsid(0) } else { *sid })
|
||||
.collect()
|
||||
}),
|
||||
cgroup: matches
|
||||
.get_many::<String>("cgroup")
|
||||
@@ -442,20 +426,31 @@ pub fn grp2gid(_name: &str) -> io::Result<u32> {
|
||||
))
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Dummy implementation for unsupported platforms.
|
||||
#[cfg(not(unix))]
|
||||
pub unsafe fn getpgrp() -> u32 {
|
||||
panic!("unsupported on this platform");
|
||||
pub fn getpgrp() -> u64 {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
rustix::process::getpgrp().as_raw_nonzero().get() as u64
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Dummy implementation for unsupported platforms.
|
||||
#[cfg(not(unix))]
|
||||
pub unsafe fn getsid(_pid: u32) -> u32 {
|
||||
panic!("unsupported on this platform");
|
||||
pub fn getsid(_pid: u32) -> u64 {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
rustix::process::getsid(None)
|
||||
.ok()
|
||||
.map(|pid: rustix::process::Pid| pid.as_raw_nonzero().get() as u64)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_uid_or_username(uid_or_username: &str) -> io::Result<u32> {
|
||||
@@ -493,26 +488,27 @@ fn test_parse_pidfile_content_valid() {
|
||||
|
||||
#[cfg(unix)]
|
||||
fn is_locked(file: &std::fs::File) -> bool {
|
||||
// On Linux, fcntl and flock locks are independent, so need to check both
|
||||
let mut flock_struct = uucore::libc::flock {
|
||||
l_type: uucore::libc::F_RDLCK as uucore::libc::c_short,
|
||||
l_whence: uucore::libc::SEEK_SET as uucore::libc::c_short,
|
||||
l_start: 0,
|
||||
l_len: 0,
|
||||
l_pid: 0,
|
||||
};
|
||||
use rustix::fs::FlockOperation;
|
||||
use std::os::fd::{AsRawFd, BorrowedFd};
|
||||
|
||||
let fd = file.as_raw_fd();
|
||||
let result = unsafe { uucore::libc::fcntl(fd, uucore::libc::F_GETLK, &mut flock_struct) };
|
||||
if result == 0 && flock_struct.l_type != uucore::libc::F_UNLCK as uucore::libc::c_short {
|
||||
return true;
|
||||
}
|
||||
// Safety: The file descriptor is valid for the duration of this function
|
||||
let borrowed_fd = unsafe { BorrowedFd::borrow_raw(fd) };
|
||||
|
||||
let result = unsafe { uucore::libc::flock(fd, uucore::libc::LOCK_SH | uucore::libc::LOCK_NB) };
|
||||
if result == -1 && std::io::Error::last_os_error().kind() == std::io::ErrorKind::WouldBlock {
|
||||
return true;
|
||||
// Try to acquire a shared lock without blocking
|
||||
match rustix::fs::flock(borrowed_fd, FlockOperation::NonBlockingLockShared) {
|
||||
Ok(_) => {
|
||||
let _ = rustix::fs::flock(borrowed_fd, FlockOperation::Unlock);
|
||||
false
|
||||
}
|
||||
Err(e)
|
||||
if e.kind() == io::ErrorKind::WouldBlock
|
||||
|| e.kind() == io::ErrorKind::PermissionDenied =>
|
||||
{
|
||||
true
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
|
||||
Reference in New Issue
Block a user