|
6 | 6 | // Common process matcher logic shared by pgrep, pkill and pidwait |
7 | 7 |
|
8 | 8 | use std::hash::Hash; |
9 | | -#[cfg(unix)] |
10 | | -use std::os::fd::AsRawFd; |
11 | 9 | use std::{collections::HashSet, io}; |
12 | 10 |
|
13 | 11 | use clap::{arg, Arg, ArgAction, ArgMatches}; |
14 | 12 | use regex::Regex; |
15 | 13 | #[cfg(unix)] |
16 | | -use uucore::libc::{getpgrp, getsid}; |
17 | | -#[cfg(unix)] |
18 | 14 | use uucore::{ |
19 | 15 | display::Quotable, |
20 | 16 | entries::{grp2gid, usr2uid}, |
@@ -91,24 +87,12 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> { |
91 | 87 | .get_many::<u32>("group") |
92 | 88 | .map(|ids| ids.cloned().collect()), |
93 | 89 | 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() |
102 | 92 | }), |
103 | 93 | 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() |
112 | 96 | }), |
113 | 97 | cgroup: matches |
114 | 98 | .get_many::<String>("cgroup") |
@@ -442,20 +426,31 @@ pub fn grp2gid(_name: &str) -> io::Result<u32> { |
442 | 426 | )) |
443 | 427 | } |
444 | 428 |
|
445 | | -/// # Safety |
446 | | -/// |
447 | 429 | /// 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 | + } |
451 | 439 | } |
452 | 440 |
|
453 | | -/// # Safety |
454 | | -/// |
455 | 441 | /// 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 | + } |
459 | 454 | } |
460 | 455 |
|
461 | 456 | fn parse_uid_or_username(uid_or_username: &str) -> io::Result<u32> { |
@@ -493,26 +488,27 @@ fn test_parse_pidfile_content_valid() { |
493 | 488 |
|
494 | 489 | #[cfg(unix)] |
495 | 490 | 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}; |
509 | 493 |
|
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, |
513 | 511 | } |
514 | | - |
515 | | - false |
516 | 512 | } |
517 | 513 |
|
518 | 514 | #[cfg(not(unix))] |
|
0 commit comments