@@ -3,6 +3,8 @@ extern crate libc;
33#[ cfg( target_os = "linux" ) ]
44use std:: fs;
55#[ cfg( target_os = "linux" ) ]
6+ use std:: ffi:: CString ;
7+ #[ cfg( target_os = "linux" ) ]
68use std:: fs:: File ;
79#[ cfg( target_os = "linux" ) ]
810use std:: io:: { BufRead , BufReader } ;
@@ -11,6 +13,9 @@ use std::{mem, process};
1113use std:: path:: PathBuf ;
1214use std:: ptr;
1315
16+ #[ cfg( not( target_os = "macos" ) ) ]
17+ use libc:: PATH_MAX ;
18+
1419use libc:: pid_t;
1520
1621use crate :: libproc:: bsd_info:: BSDInfo ;
@@ -19,7 +24,7 @@ use crate::libproc::task_info::{TaskAllInfo, TaskInfo};
1924use crate :: libproc:: thread_info:: ThreadInfo ;
2025use crate :: libproc:: work_queue_info:: WorkQueueInfo ;
2126
22- use self :: libc:: { c_int, c_void} ;
27+ use self :: libc:: { c_char , c_int, c_void, readlink } ;
2328
2429// Since we cannot access C macros for constants from Rust - I have had to redefine this, based on Apple's source code
2530// See http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
@@ -282,7 +287,15 @@ pub fn pidpath(pid: i32) -> Result<String, String> {
282287
283288#[ cfg( target_os = "linux" ) ]
284289pub fn pidpath ( pid : i32 ) -> Result < String , String > {
285- unimplemented ! ( )
290+ let exe_path = CString :: new ( format ! ( "/proc/{}/exe" , pid) ) . unwrap ( ) ;
291+ let mut buf: Vec < u8 > = Vec :: with_capacity ( PATH_MAX as usize - 1 ) ;
292+ let buffer_ptr = buf. as_mut_ptr ( ) as * mut c_char ;
293+ let buffer_size = buf. capacity ( ) ;
294+ let ret = unsafe {
295+ readlink ( exe_path. as_ptr ( ) , buffer_ptr, buffer_size)
296+ } ;
297+
298+ helpers:: check_errno ( ret as i32 , & mut buf)
286299}
287300
288301/// Returns the major and minor version numbers of the native librproc library being used
@@ -559,13 +572,18 @@ mod test {
559572 }
560573 }
561574
562- # [ cfg ( target_os = "macos" ) ]
575+ //
563576 #[ test]
564577 // This checks that it cannot find the path of the process with pid -1 and returns correct error messaage
565578 fn pidpath_test_unknown_pid ( ) {
579+ #[ cfg( target_os = "macos" ) ]
580+ let error_message = "No such process" ;
581+ #[ cfg( target_os = "linux" ) ]
582+ let error_message = "No such file or directory" ;
583+
566584 match pidpath ( -1 ) {
567585 Ok ( path) => assert ! ( false , "It found the path of process Pwith ID = -1 (path = {}), that's not possible\n " , path) ,
568- Err ( message) => assert ! ( message. contains( "No such process" ) )
586+ Err ( message) => assert ! ( message. contains( error_message ) ) ,
569587 }
570588 }
571589
@@ -580,4 +598,4 @@ mod test {
580598 fn test_pidcwd_of_self ( ) {
581599 assert_eq ! ( env:: current_dir( ) . unwrap( ) , pidcwd( process:: id( ) as i32 ) . unwrap( ) ) ;
582600 }
583- }
601+ }
0 commit comments