@@ -324,7 +324,11 @@ mod linux {
324324 }
325325 }
326326
327- pub fn get_matched_procs ( file : Vec < PathBuf > , mount : bool ) -> Result < Vec < Names > , io:: Error > {
327+ pub fn get_matched_procs (
328+ file : Vec < PathBuf > ,
329+ mount : bool ,
330+ named_files : bool ,
331+ ) -> Result < Vec < Names > , io:: Error > {
328332 let (
329333 mut names,
330334 mut unix_socket_list,
@@ -343,6 +347,7 @@ mod linux {
343347 NameSpace :: File => handle_file_namespace (
344348 name,
345349 mount,
350+ named_files,
346351 & mut mount_list,
347352 & mut inode_list,
348353 & mut device_list,
@@ -1087,7 +1092,8 @@ mod linux {
10871092 /// # Arguments
10881093 ///
10891094 /// * `names` - A mutable reference to a `Names` object containing the file path.
1090- /// * `mount` - A boolean indicating whether to handle mount information or not.
1095+ /// * `mount` - A boolean indicating whether to handle mount information or not (-c flag).
1096+ /// * `named_files` - A boolean indicating report only for named files (-f flag).
10911097 /// * `mount_list` - A mutable reference to a `MountList` for reading mount points.
10921098 /// * `inode_list` - A mutable reference to an `InodeList` for updating inode information.
10931099 /// * `device_list` - A mutable reference to a `DeviceList` for updating device information.
@@ -1102,6 +1108,7 @@ mod linux {
11021108 fn handle_file_namespace (
11031109 names : & mut Names ,
11041110 mount : bool ,
1111+ named_files : bool ,
11051112 mount_list : & mut MountList ,
11061113 inode_list : & mut InodeList ,
11071114 device_list : & mut DeviceList ,
@@ -1112,7 +1119,14 @@ mod linux {
11121119 let st = timeout ( & names. filename . to_string_lossy ( ) , 5 ) ?;
11131120 read_proc_mounts ( mount_list) ?;
11141121
1115- if mount {
1122+ // POSIX: For block special devices, all processes using any file on
1123+ // that device are listed (unless -f is specified).
1124+ // -c (mount): Treat file as mount point, report on any files in filesystem.
1125+ // -f (named_files): Report only for the named files.
1126+ let is_block_device = ( st. mode ( ) & libc:: S_IFMT ) == libc:: S_IFBLK ;
1127+ let use_device_mode = mount || ( is_block_device && !named_files) ;
1128+
1129+ if use_device_mode {
11161130 * device_list = DeviceList :: new ( names. clone ( ) , st. dev ( ) ) ;
11171131 * need_check_map = true ;
11181132 } else {
@@ -1302,6 +1316,7 @@ mod macos {
13021316 pub fn get_matched_procs (
13031317 file : Vec < PathBuf > ,
13041318 mount : bool ,
1319+ named_files : bool ,
13051320 ) -> Result < Vec < Names > , Box < dyn std:: error:: Error > > {
13061321 let mut names: Vec < Names > = file
13071322 . iter ( )
@@ -1312,10 +1327,17 @@ mod macos {
13121327 let st = timeout ( & name. filename . to_string_lossy ( ) , 5 ) ?;
13131328 let uid = st. uid ( ) ;
13141329
1330+ // POSIX: For block special devices, all processes using any file on
1331+ // that device are listed (unless -f is specified).
1332+ // -c (mount): Treat file as mount point, report on any files in filesystem.
1333+ // -f (named_files): Report only for the named files.
1334+ let is_block_device = ( st. mode ( ) & libc:: S_IFMT ) == libc:: S_IFBLK ;
1335+ let is_volume = mount || ( is_block_device && !named_files) ;
1336+
13151337 let pids = listpidspath (
13161338 osx_libproc_bindings:: PROC_ALL_PIDS ,
13171339 Path :: new ( & name. filename ) ,
1318- mount ,
1340+ is_volume ,
13191341 false ,
13201342 ) ?;
13211343
@@ -1416,17 +1438,19 @@ fn print_matches(name: &mut Names, user: bool) -> Result<(), io::Error> {
14161438
14171439 eprint ! ( "{}" , access) ;
14181440 if user {
1419- let owner = unsafe {
1441+ let owner_str : String = unsafe {
14201442 let pw_entry = libc:: getpwuid ( uid) ;
14211443 if pw_entry. is_null ( ) {
1422- "unknownr"
1444+ // POSIX: if user name cannot be resolved, print the real user ID
1445+ uid. to_string ( )
14231446 } else {
14241447 CStr :: from_ptr ( ( * pw_entry) . pw_name )
14251448 . to_str ( )
1426- . unwrap_or ( "invalid_string" )
1449+ . unwrap_or ( & uid. to_string ( ) )
1450+ . to_string ( )
14271451 }
14281452 } ;
1429- eprint ! ( "({})" , owner ) ;
1453+ eprint ! ( "({})" , owner_str ) ;
14301454 }
14311455 io:: stderr ( ) . flush ( ) ?;
14321456 }
@@ -1480,7 +1504,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
14801504 bind_textdomain_codeset ( "posixutils-rs" , "UTF-8" ) ?;
14811505
14821506 let Args {
1483- mount, user, file, ..
1507+ mount,
1508+ named_files,
1509+ user,
1510+ file,
14841511 } = Args :: try_parse ( ) . unwrap_or_else ( |err| match err. kind ( ) {
14851512 clap:: error:: ErrorKind :: DisplayHelp | clap:: error:: ErrorKind :: DisplayVersion => {
14861513 print ! ( "{err}" ) ;
@@ -1496,10 +1523,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
14961523 } ) ;
14971524
14981525 #[ cfg( target_os = "linux" ) ]
1499- let mut names = linux:: get_matched_procs ( file, mount) ?;
1526+ let mut names = linux:: get_matched_procs ( file, mount, named_files ) ?;
15001527
15011528 #[ cfg( target_os = "macos" ) ]
1502- let mut names = macos:: get_matched_procs ( file, mount) ?;
1529+ let mut names = macos:: get_matched_procs ( file, mount, named_files ) ?;
15031530
15041531 for name in names. iter_mut ( ) {
15051532 print_matches ( name, user) ?;
0 commit comments