Skip to content

Commit 8983665

Browse files
Merge pull request #626 from Franklin-Qi/remove-libc-in-pgrep
pgrep: remove libc in pgrep
2 parents 6d9c3d8 + f4d9c07 commit 8983665

3 files changed

Lines changed: 63 additions & 57 deletions

File tree

src/uu/pgrep/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ workspace = true
1616
[dependencies]
1717
clap = { workspace = true }
1818
regex = { workspace = true }
19-
rustix = { workspace = true }
19+
rustix = { workspace = true, features = ["fs", "process", "thread"] }
2020
uucore = { workspace = true, features = ["entries", "signals", "process"] }
2121
walkdir = { workspace = true }
2222

src/uu/pgrep/src/process.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl Teletype {
120120

121121
#[cfg(target_os = "linux")]
122122
fn from_tty_nr_impl(tty_nr: u64, drivers: &[TtyDriverEntry]) -> Self {
123-
use uucore::libc::{major, minor};
123+
use rustix::fs::{major, minor};
124124

125125
if tty_nr == 0 {
126126
return Self::Unknown;
@@ -843,7 +843,7 @@ unknown /dev/tty 4 1-63 console"#;
843843
];
844844

845845
for (major, minor, expected) in test_cases {
846-
let tty_nr = uucore::libc::makedev(major, minor);
846+
let tty_nr = rustix::fs::makedev(major, minor);
847847
let result = Teletype::from_tty_nr_impl(tty_nr, &parsed_entries);
848848
assert_eq!(result, expected);
849849
}
@@ -904,14 +904,14 @@ unknown /dev/tty 4 1-63 console"#;
904904
#[test]
905905
#[cfg(target_os = "linux")]
906906
fn test_thread_ids() {
907-
let main_tid = unsafe { uucore::libc::gettid() };
907+
let main_tid = rustix::thread::gettid().as_raw_nonzero().get() as u64;
908908
std::thread::spawn(move || {
909909
let mut pid_entry = ProcessInformation::current_process_info().unwrap();
910910
let thread_ids = pid_entry.thread_ids();
911911

912912
assert!(thread_ids.contains(&(main_tid as usize)));
913913

914-
let new_thread_tid = unsafe { uucore::libc::gettid() };
914+
let new_thread_tid = rustix::thread::gettid().as_raw_nonzero().get() as u64;
915915
assert!(thread_ids.contains(&(new_thread_tid as usize)));
916916
})
917917
.join()
@@ -939,14 +939,24 @@ unknown /dev/tty 4 1-63 console"#;
939939
let mut pid_entry = ProcessInformation::current_process_info().unwrap();
940940
assert_eq!(
941941
pid_entry.ppid().unwrap(),
942-
unsafe { uucore::libc::getppid() } as u64
942+
rustix::process::getppid()
943+
.map(|pid| pid.as_raw_nonzero().get() as u64)
944+
.unwrap_or(0)
943945
);
944946
assert_eq!(
945947
pid_entry.pgid().unwrap(),
946-
unsafe { uucore::libc::getpgid(0) } as u64
948+
rustix::process::getpgid(None)
949+
.ok()
950+
.map(|pid| pid.as_raw_nonzero().get() as u64)
951+
.unwrap_or(0)
952+
);
953+
assert_eq!(
954+
pid_entry.sid().unwrap(),
955+
rustix::process::getsid(None)
956+
.ok()
957+
.map(|pid| pid.as_raw_nonzero().get() as u64)
958+
.unwrap_or(0)
947959
);
948-
assert_eq!(pid_entry.sid().unwrap(), unsafe { uucore::libc::getsid(0) }
949-
as u64);
950960
}
951961

952962
#[test]

src/uu/pgrep/src/process_matcher.rs

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,11 @@
66
// Common process matcher logic shared by pgrep, pkill and pidwait
77

88
use std::hash::Hash;
9-
#[cfg(unix)]
10-
use std::os::fd::AsRawFd;
119
use std::{collections::HashSet, io};
1210

1311
use clap::{arg, Arg, ArgAction, ArgMatches};
1412
use regex::Regex;
1513
#[cfg(unix)]
16-
use uucore::libc::{getpgrp, getsid};
17-
#[cfg(unix)]
1814
use uucore::{
1915
display::Quotable,
2016
entries::{grp2gid, usr2uid},
@@ -91,24 +87,12 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
9187
.get_many::<u32>("group")
9288
.map(|ids| ids.cloned().collect()),
9389
pgroup: matches.get_many::<u64>("pgroup").map(|xs| {
94-
xs.map(|pg| {
95-
if *pg == 0 {
96-
unsafe { getpgrp() as u64 }
97-
} else {
98-
*pg
99-
}
100-
})
101-
.collect()
90+
xs.map(|pg| if *pg == 0 { getpgrp() } else { *pg })
91+
.collect()
10292
}),
10393
session: matches.get_many::<u64>("session").map(|xs| {
104-
xs.map(|sid| {
105-
if *sid == 0 {
106-
unsafe { getsid(0) as u64 }
107-
} else {
108-
*sid
109-
}
110-
})
111-
.collect()
94+
xs.map(|sid| if *sid == 0 { getsid(0) } else { *sid })
95+
.collect()
11296
}),
11397
cgroup: matches
11498
.get_many::<String>("cgroup")
@@ -442,20 +426,31 @@ pub fn grp2gid(_name: &str) -> io::Result<u32> {
442426
))
443427
}
444428

445-
/// # Safety
446-
///
447429
/// Dummy implementation for unsupported platforms.
448-
#[cfg(not(unix))]
449-
pub unsafe fn getpgrp() -> u32 {
450-
panic!("unsupported on this platform");
430+
pub fn getpgrp() -> u64 {
431+
#[cfg(unix)]
432+
{
433+
rustix::process::getpgrp().as_raw_nonzero().get() as u64
434+
}
435+
#[cfg(not(unix))]
436+
{
437+
0
438+
}
451439
}
452440

453-
/// # Safety
454-
///
455441
/// Dummy implementation for unsupported platforms.
456-
#[cfg(not(unix))]
457-
pub unsafe fn getsid(_pid: u32) -> u32 {
458-
panic!("unsupported on this platform");
442+
pub fn getsid(_pid: u32) -> u64 {
443+
#[cfg(unix)]
444+
{
445+
rustix::process::getsid(None)
446+
.ok()
447+
.map(|pid: rustix::process::Pid| pid.as_raw_nonzero().get() as u64)
448+
.unwrap_or(0)
449+
}
450+
#[cfg(not(unix))]
451+
{
452+
0
453+
}
459454
}
460455

461456
fn parse_uid_or_username(uid_or_username: &str) -> io::Result<u32> {
@@ -493,26 +488,27 @@ fn test_parse_pidfile_content_valid() {
493488

494489
#[cfg(unix)]
495490
fn is_locked(file: &std::fs::File) -> bool {
496-
// On Linux, fcntl and flock locks are independent, so need to check both
497-
let mut flock_struct = uucore::libc::flock {
498-
l_type: uucore::libc::F_RDLCK as uucore::libc::c_short,
499-
l_whence: uucore::libc::SEEK_SET as uucore::libc::c_short,
500-
l_start: 0,
501-
l_len: 0,
502-
l_pid: 0,
503-
};
504-
let fd = file.as_raw_fd();
505-
let result = unsafe { uucore::libc::fcntl(fd, uucore::libc::F_GETLK, &mut flock_struct) };
506-
if result == 0 && flock_struct.l_type != uucore::libc::F_UNLCK as uucore::libc::c_short {
507-
return true;
508-
}
491+
use rustix::fs::FlockOperation;
492+
use std::os::fd::{AsRawFd, BorrowedFd};
509493

510-
let result = unsafe { uucore::libc::flock(fd, uucore::libc::LOCK_SH | uucore::libc::LOCK_NB) };
511-
if result == -1 && std::io::Error::last_os_error().kind() == std::io::ErrorKind::WouldBlock {
512-
return true;
494+
let fd = file.as_raw_fd();
495+
// Safety: The file descriptor is valid for the duration of this function
496+
let borrowed_fd = unsafe { BorrowedFd::borrow_raw(fd) };
497+
498+
// Try to acquire a shared lock without blocking
499+
match rustix::fs::flock(borrowed_fd, FlockOperation::NonBlockingLockShared) {
500+
Ok(_) => {
501+
let _ = rustix::fs::flock(borrowed_fd, FlockOperation::Unlock);
502+
false
503+
}
504+
Err(e)
505+
if e.kind() == io::ErrorKind::WouldBlock
506+
|| e.kind() == io::ErrorKind::PermissionDenied =>
507+
{
508+
true
509+
}
510+
Err(_) => false,
513511
}
514-
515-
false
516512
}
517513

518514
#[cfg(not(unix))]

0 commit comments

Comments
 (0)