Skip to content

Commit b35c098

Browse files
Add ThreadInfo and WorkQueueInfo examples and tests (#137)
* Remove redundant imports and simplify doc example * Add doc example for TaskInfo * Add ThreadInfo doc example/test and a unit test for it * Add WorkQueueInfo doc example/test and a unit test for it
1 parent 657db92 commit b35c098

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

src/libproc/file_info.rs

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ impl From<u32> for ProcFDType {
8787
}
8888
}
8989

90-
/// The `PIDFDInfo` trait is needed for polymorphism on pidfdinfo types, also abstracting flavor in order to provide
91-
/// type-guaranteed flavor correctness
90+
/// The `PIDFDInfo` trait is needed for polymorphism on pidfdinfo types, also abstracting flavor
91+
/// in order to provide type-guaranteed flavor correctness
9292
pub trait PIDFDInfo: Default {
9393
/// Return the Pid File Descriptor Info flavor of the implementing struct
9494
fn flavor() -> PIDFDInfoFlavor;
@@ -105,7 +105,7 @@ pub trait PIDFDInfo: Default {
105105
/// ```
106106
/// use std::io::Write;
107107
/// use std::net::TcpListener;
108-
/// use libproc::libproc::proc_pid::{listpidinfo, pidinfo, ListThreads};
108+
/// use libproc::libproc::proc_pid::{listpidinfo, pidinfo};
109109
/// use libproc::libproc::bsd_info::{BSDInfo};
110110
/// use libproc::libproc::net_info::{SocketFDInfo, SocketInfoKind};
111111
/// use libproc::libproc::file_info::{pidfdinfo, ListFDs, ProcFDType};
@@ -116,45 +116,38 @@ pub trait PIDFDInfo: Default {
116116
/// // Open TCP port:8000 to test.
117117
/// let _listener = TcpListener::bind("127.0.0.1:8000");
118118
///
119-
/// if let Ok(info) = pidinfo::<BSDInfo>(pid, 0) {
120-
/// if let Ok(fds) = listpidinfo::<ListFDs>(pid, info.pbi_nfiles as usize) {
121-
/// for fd in &fds {
122-
/// match fd.proc_fdtype.into() {
123-
/// ProcFDType::Socket => {
124-
/// if let Ok(socket) = pidfdinfo::<SocketFDInfo>(pid, fd.proc_fd) {
125-
/// match socket.psi.soi_kind.into() {
126-
/// SocketInfoKind::Tcp => {
127-
/// // access to the member of `soi_proto` is unsafe becasuse of union type.
128-
/// let info = unsafe { socket.psi.soi_proto.pri_tcp };
119+
/// let info = pidinfo::<BSDInfo>(pid, 0).expect("Could not get BSDInfo on {pid}");///
120+
/// let fds = listpidinfo::<ListFDs>(pid, info.pbi_nfiles as usize)
121+
/// .expect("Could not list FD of {pid}");
122+
/// for fd in &fds {
123+
/// if let(ProcFDType::Socket) = fd.proc_fdtype.into() {
124+
/// let socket = pidfdinfo::<SocketFDInfo>(pid, fd.proc_fd)
125+
/// .expect("Could not get SocketFDInfo");
126+
/// if let(SocketInfoKind::Tcp) = socket.psi.soi_kind.into() {
127+
/// // access to the member of `soi_proto` is unsafe becasuse of union type.
128+
/// let info = unsafe { socket.psi.soi_proto.pri_tcp };
129129
///
130-
/// // change endian and cut off because insi_lport is network endian and 16bit witdh.
131-
/// let mut port = 0;
132-
/// port |= info.tcpsi_ini.insi_lport >> 8 & 0x00ff;
133-
/// port |= info.tcpsi_ini.insi_lport << 8 & 0xff00;
130+
/// // change endian and cut off because insi_lport is network endian and 16bit witdh.
131+
/// let mut port = 0;
132+
/// port |= info.tcpsi_ini.insi_lport >> 8 & 0x00ff;
133+
/// port |= info.tcpsi_ini.insi_lport << 8 & 0xff00;
134134
///
135-
/// // access to the member of `insi_laddr` is unsafe becasuse of union type.
136-
/// let s_addr = unsafe { info.tcpsi_ini.insi_laddr.ina_46.i46a_addr4.s_addr };
135+
/// // access to the member of `insi_laddr` is unsafe becasuse of union type.
136+
/// let s_addr = unsafe { info.tcpsi_ini.insi_laddr.ina_46.i46a_addr4.s_addr };
137137
///
138-
/// // change endian because insi_laddr is network endian.
139-
/// let mut addr = 0;
140-
/// addr |= s_addr >> 24 & 0x000000ff;
141-
/// addr |= s_addr >> 8 & 0x0000ff00;
142-
/// addr |= s_addr << 8 & 0x00ff0000;
143-
/// addr |= s_addr << 24 & 0xff000000;
138+
/// // change endian because insi_laddr is network endian.
139+
/// let mut addr = 0;
140+
/// addr |= s_addr >> 24 & 0x000000ff;
141+
/// addr |= s_addr >> 8 & 0x0000ff00;
142+
/// addr |= s_addr << 8 & 0x00ff0000;
143+
/// addr |= s_addr << 24 & 0xff000000;
144144
///
145-
/// println!("{}.{}.{}.{}:{}", addr >> 24 & 0xff, addr >> 16 & 0xff, addr >> 8 & 0xff, addr & 0xff, port);
146-
/// }
147-
/// _ => (),
148-
/// }
149-
/// }
150-
/// }
151-
/// _ => (),
152-
/// }
145+
/// println!("{}.{}.{}.{}:{}", addr >> 24 & 0xff, addr >> 16 & 0xff, addr >> 8 & 0xff,
146+
/// addr & 0xff, port);
153147
/// }
154148
/// }
155149
/// }
156150
/// ```
157-
///
158151
#[cfg(target_os = "macos")]
159152
pub fn pidfdinfo<T: PIDFDInfo>(pid: i32, fd: i32) -> Result<T, String> {
160153
let flavor = T::flavor() as i32;

src/libproc/proc_pid.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,11 @@ pub fn listpidspath(proc_types: ProcType, path: &str) -> Result<Vec<u32>, String
205205
}
206206

207207
/// Get info about a process, task, thread or work queue by specifying the appropriate type for `T`:
208-
/// - `BSDInfo`
209-
/// - `TaskInfo`
210-
/// - `TaskAllInfo`
211-
/// - `ThreadInfo`
212-
/// - `WorkQueueInfo`
208+
/// - `BSDInfo` - see struct `proc_bsdinfo` in generated `osx_libproc_bindings.rs`
209+
/// - `TaskInfo` - see struct `proc_taskinfo` in generated `osx_libproc_bindings.rs`
210+
/// - `TaskAllInfo` - see struct `TaskAllInfo` in `task_info.rs` that contains the two structs above
211+
/// - `ThreadInfo` - see struct `proc_threadinfo` in generated `osx_libproc_bindings.rs`
212+
/// - `WorkQueueInfo` - see struct `proc_workqueueinfo` in generated `osx_libproc_bindings.rs`
213213
///
214214
/// # Errors
215215
///
@@ -219,17 +219,47 @@ pub fn listpidspath(proc_types: ProcType, path: &str) -> Result<Vec<u32>, String
219219
///
220220
/// ```
221221
/// use std::io::Write;
222-
/// use libproc::libproc::proc_pid::pidinfo;
223-
/// use libproc::libproc::bsd_info::BSDInfo;
222+
/// use libproc::proc_pid::pidinfo;
223+
/// use libproc::bsd_info::BSDInfo;
224+
/// use libproc::task_info::{TaskAllInfo, TaskInfo};
224225
/// use std::process;
226+
/// use libproc::thread_info::ThreadInfo;
227+
/// use libproc::work_queue_info::WorkQueueInfo;
225228
///
226229
/// let pid = process::id() as i32;
227230
///
228-
/// // Get the `BSDInfo` for Process of pid 0
231+
/// // Get the `BSDInfo` for process with pid 0
229232
/// match pidinfo::<BSDInfo>(pid, 0) {
230233
/// Ok(info) => assert_eq!(info.pbi_pid as i32, pid),
231234
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
232235
/// };
236+
///
237+
/// // Get the `TaskInfo` for process with pid 0
238+
/// match pidinfo::<TaskInfo>(pid, 0) {
239+
/// Ok(info) => assert!(info.pti_threadnum > 0),
240+
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
241+
/// };
242+
///
243+
/// // Get the `TaskAllInfo` for process with pid 0
244+
/// match pidinfo::<TaskAllInfo>(pid, 0) {
245+
/// Ok(info) => {
246+
/// assert_eq!(info.pbsd.pbi_pid as i32, pid);
247+
/// assert!(info.ptinfo.pti_threadnum > 0);
248+
/// }
249+
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
250+
/// };
251+
///
252+
/// // Get the `ThreadInfo` for process with pid 0
253+
/// match pidinfo::<ThreadInfo>(pid, 0) {
254+
/// Ok(info) => assert!(!info.pth_name.is_empty()),
255+
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
256+
/// };
257+
///
258+
/// // Get the `WorkQueueInfo` for process with pid 0
259+
/// match pidinfo::<WorkQueueInfo>(pid, 0) {
260+
/// Ok(info) => assert!(info.pwq_nthreads > 0),
261+
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
262+
/// };
233263
/// ```
234264
#[cfg(target_os = "macos")]
235265
pub fn pidinfo<T: PIDInfo>(pid: i32, arg: u64) -> Result<T, String> {
@@ -670,25 +700,19 @@ mod test {
670700
};
671701
}
672702

673-
#[ignore]
674703
#[cfg(target_os = "macos")]
675704
#[test]
676705
fn threadinfo_test() {
677-
let pid = process::id() as i32;
678-
679-
match pidinfo::<ThreadInfo>(pid, 0) {
680-
Ok(info) => assert!(info.pth_user_time > 0),
706+
match pidinfo::<ThreadInfo>(0, 0) {
707+
Ok(info) => assert!(!info.pth_name.is_empty()),
681708
Err(e) => panic!("Error retrieving ThreadInfo: {}", e),
682709
};
683710
}
684711

685-
#[ignore]
686712
#[cfg(target_os = "macos")]
687713
#[test]
688714
fn workqueueinfo_test() {
689-
let pid = process::id() as i32;
690-
691-
match pidinfo::<WorkQueueInfo>(pid, 0) {
715+
match pidinfo::<WorkQueueInfo>(1, 0) {
692716
Ok(info) => assert!(info.pwq_nthreads > 0),
693717
Err(e) => panic!("{}: {}", "Error retrieving WorkQueueInfo", e),
694718
};

0 commit comments

Comments
 (0)