@@ -34,9 +34,9 @@ impl From<ProcFilter> for u32 {
3434
3535// similar to list_pids_ret() below, there are two cases when 0 is returned, one when there are
3636// no pids, and the other when there is an error
37+ // when `errno` is set to indicate an error in the input type, the return value is 0
3738fn check_listpid_ret ( ret : c_int ) -> io:: Result < Vec < u32 > > {
38- let errno = std:: io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap_or ( 0 ) ;
39- if ret < 0 || ( ret == 0 && errno < 0 ) {
39+ if ret < 0 || ( ret == 0 && io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap_or ( 0 ) != 0 ) {
4040 return Err ( io:: Error :: last_os_error ( ) ) ;
4141 }
4242
@@ -47,10 +47,13 @@ fn check_listpid_ret(ret: c_int) -> io::Result<Vec<u32>> {
4747// Common code for handling the special case of listpids return, where 0 is a valid return
4848// but is also used in the error case - so we need to look at errno to distringish between a valid
4949// 0 return and an error return
50+ // when `errno` is set to indicate an error in the input type, the return value is 0
5051fn list_pids_ret ( ret : c_int , mut pids : Vec < u32 > ) -> io:: Result < Vec < u32 > > {
51- let errno = std:: io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap_or ( 0 ) ;
5252 match ret {
53- value if value < 0 || errno < 0 => Err ( io:: Error :: last_os_error ( ) ) ,
53+ value if value < 0 ||
54+ ( ret == 0 && io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap_or ( 0 ) != 0 ) => {
55+ Err ( io:: Error :: last_os_error ( ) )
56+ } ,
5457 _ => {
5558 let items_count = ret as usize / mem:: size_of :: < u32 > ( ) ;
5659 unsafe {
@@ -270,7 +273,7 @@ mod test {
270273 fn test_listpids_real_uid ( ) {
271274 let mut bsdinfo_ruids: HashMap < _ , HashSet < _ > > = HashMap :: new ( ) ;
272275 for info in get_all_pid_bsdinfo ( )
273- . expect ( "Could not get all pids info" ) {
276+ . expect ( "Could not get all pids info" ) {
274277 bsdinfo_ruids
275278 . entry ( info. pbi_ruid )
276279 . and_modify ( |pids| {
@@ -330,6 +333,13 @@ mod test {
330333 assert ! ( not_matched <= PROCESS_DIFF_TOLERANCE ) ;
331334 }
332335
336+ #[ test]
337+ fn test_listpids_invalid_parent_pid ( ) {
338+ let pids = listpids ( ProcFilter :: ByParentProcess { ppid : u32:: MAX } )
339+ . expect ( "Error requesting children of inexistant process" ) ;
340+ assert ! ( pids. is_empty( ) ) ;
341+ }
342+
333343 // No point in writing test cases for all ProcFilter members, as the Darwin
334344 // implementation of proc_listpidspath is essentially a wrapper acound
335345 // proc_listpids with calls to proc_pidinfo to gather path information.
@@ -339,8 +349,9 @@ mod test {
339349 #[ test]
340350 fn test_listpidspath ( ) -> Result < ( ) , io:: Error > {
341351 let root = std:: path:: Path :: new ( "/" ) ;
342- let pids =
343- listpidspath ( ProcFilter :: All , root, true , false ) . expect ( "Failed to load PIDs for path" ) ;
352+ let pids: Vec < u32 > =
353+ listpidspath ( ProcFilter :: All , root, true , false )
354+ . expect ( "Failed to load PIDs for path" ) ;
344355 assert ! ( !pids. is_empty( ) ) ;
345356 Ok ( ( ) )
346357 }
0 commit comments