Skip to content

Commit b5d30db

Browse files
Merge pull request #16 from dalance/listpidinfo
Add listpidinfo and ListThreads/ListFDs
2 parents 2a60b91 + 92c5172 commit b5d30db

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

src/libproc/proc_pid.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,137 @@ fn name_test_init_pid() {
503503
Err(message) => assert!(true, message)
504504
}
505505
}
506+
507+
// This trait is needed for polymorphism on listpidinfo types, also abstracting flavor in order to provide
508+
// type-guaranteed flavor correctness
509+
pub trait ListPIDInfo {
510+
type Item;
511+
fn flavor() -> PidInfoFlavor;
512+
}
513+
514+
/// Returns the information of the process that match pid passed in.
515+
/// `max_len` is the maximum number of array to return.
516+
/// The length of return value: `Vec<T::Item>` may be less than `max_len`.
517+
///
518+
/// # Examples
519+
///
520+
/// ```
521+
/// use std::io::Write;
522+
/// use libproc::libproc::proc_pid::{listpidinfo, pidinfo, ListFDs, TaskAllInfo, ProcFDType};
523+
///
524+
/// fn listpidinfo_test() {
525+
/// use std::process;
526+
/// let pid = process::id() as i32;
527+
///
528+
/// if let Ok(info) = pidinfo::<TaskAllInfo>(pid, 0) {
529+
/// if let Ok(fds) = listpidinfo::<ListFDs>(pid, info.pbsd.pbi_nfiles as usize) {
530+
/// for fd in &fds {
531+
/// let fd_type = ProcFDType::from(fd.proc_fdtype);
532+
/// println!("File Descriptor: {}, Type: {:?}", fd.proc_fd, fd_type);
533+
/// }
534+
/// }
535+
/// }
536+
/// }
537+
/// ```
538+
pub fn listpidinfo<T: ListPIDInfo>(pid : i32, max_len: usize) -> Result<Vec<T::Item>, String> {
539+
let flavor = T::flavor() as i32;
540+
let buffer_size = mem::size_of::<T::Item>() as i32 * max_len as i32;
541+
let mut buffer = Vec::<T::Item>::with_capacity(max_len);
542+
let buffer_ptr = unsafe {
543+
buffer.set_len(max_len);
544+
buffer.as_mut_ptr() as *mut c_void
545+
};
546+
547+
let ret: i32;
548+
549+
unsafe {
550+
ret = proc_pidinfo( pid, flavor, 0, buffer_ptr, buffer_size);
551+
};
552+
553+
if ret <= 0 {
554+
Err(get_errno_with_message(ret))
555+
} else {
556+
let actual_len = ret as usize / mem::size_of::<T::Item>();
557+
buffer.truncate(actual_len);
558+
Ok(buffer)
559+
}
560+
}
561+
562+
#[test]
563+
fn listpidinfo_test() {
564+
use std::process;
565+
let pid = process::id() as i32;
566+
567+
match pidinfo::<TaskAllInfo>(pid, 0) {
568+
Ok(info) => {
569+
match listpidinfo::<ListThreads>(pid, info.ptinfo.pti_threadnum as usize) {
570+
Ok(threads) => assert!(threads.len()>0),
571+
Err(err) => assert!(false, "Error retrieving process info: {}", err)
572+
}
573+
match listpidinfo::<ListFDs>(pid, info.pbsd.pbi_nfiles as usize) {
574+
Ok(fds) => assert!(fds.len()>0),
575+
Err(err) => assert!(false, "Error retrieving process info: {}", err)
576+
}
577+
},
578+
Err(err) => assert!(false, "Error retrieving process info: {}", err)
579+
};
580+
}
581+
582+
pub struct ListThreads;
583+
584+
impl ListPIDInfo for ListThreads {
585+
type Item = uint64_t;
586+
fn flavor() -> PidInfoFlavor { PidInfoFlavor::ListThreads }
587+
}
588+
589+
pub struct ListFDs;
590+
591+
impl ListPIDInfo for ListFDs {
592+
type Item = ProcFDInfo;
593+
fn flavor() -> PidInfoFlavor { PidInfoFlavor::ListFDs }
594+
}
595+
596+
#[repr(C)]
597+
pub struct ProcFDInfo {
598+
pub proc_fd: int32_t,
599+
pub proc_fdtype: uint32_t,
600+
}
601+
602+
#[derive(Copy, Clone, Debug)]
603+
pub enum ProcFDType {
604+
/// AppleTalk
605+
ATalk = 0,
606+
/// Vnode
607+
VNode = 1,
608+
/// Socket
609+
Socket = 2,
610+
/// POSIX shared memory
611+
PSHM = 3,
612+
/// POSIX semaphore
613+
PSEM = 4,
614+
/// Kqueue
615+
KQueue = 5,
616+
/// Pipe
617+
Pipe = 6,
618+
/// FSEvents
619+
FSEvents = 7,
620+
/// Unknown
621+
Unknown,
622+
}
623+
624+
impl From<uint32_t> for ProcFDType {
625+
fn from(value: uint32_t) -> ProcFDType {
626+
match value {
627+
0 => ProcFDType::ATalk ,
628+
1 => ProcFDType::VNode ,
629+
2 => ProcFDType::Socket ,
630+
3 => ProcFDType::PSHM ,
631+
4 => ProcFDType::PSEM ,
632+
5 => ProcFDType::KQueue ,
633+
6 => ProcFDType::Pipe ,
634+
7 => ProcFDType::FSEvents,
635+
_ => ProcFDType::Unknown ,
636+
}
637+
}
638+
}
639+

0 commit comments

Comments
 (0)