Skip to content

Commit b36d9bc

Browse files
Merge pull request #56 from andrewdavidmackenzie/add_new_calls
Add support for proc_listpidspath() call
2 parents 8ccceb8 + 27f0575 commit b36d9bc

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub fn kmsgbuf() -> Result<String, String>
7575
- `dmesg` is a version of dmesg implemented in rust that uses libproc-rs.
7676

7777
# Platforms
78-
Mac OS X and work started on Linux.
78+
Mac OS X (10.5 and above) and Linux.
7979

8080
# Build and Test
8181
`cargo test` should build and test as usual for rust projects.

src/libproc/file_info.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use self::libc::{c_int, c_void};
1313
#[cfg(target_os = "macos")]
1414
#[link(name = "proc", kind = "dylib")]
1515
extern {
16+
// This method is supported in the minimum version of Mac OS X which is 10.5
1617
fn proc_pidfdinfo(pid: c_int, fd: c_int, flavor: c_int, buffer: *mut c_void, buffersize: c_int) -> c_int;
1718
}
1819

src/libproc/kmesg_buffer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const MAX_MSG_BSIZE: usize = 1024 * 1024;
2727
#[cfg(target_os = "macos")]
2828
#[link(name = "proc", kind = "dylib")]
2929
extern {
30+
// This method is supported in the minimum version of Mac OS X which is 10.5
3031
fn proc_kmsgbuf(buffer: *mut c_void, buffersize: u32) -> c_int;
3132
}
3233

src/libproc/proc_pid.rs

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::libproc::work_queue_info::WorkQueueInfo;
2828
#[cfg(target_os = "linux")]
2929
use self::libc::{c_char, readlink};
3030
#[cfg(target_os = "macos")]
31-
use self::libc::{c_int, c_void};
31+
use self::libc::{c_int, c_void, c_char};
3232

3333
// Since we cannot access C macros for constants from Rust - I have had to redefine this, based on Apple's source code
3434
// See http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
@@ -135,21 +135,18 @@ impl ListPIDInfo for ListThreads {
135135
#[cfg(target_os = "macos")]
136136
#[link(name = "proc", kind = "dylib")]
137137
extern {
138+
// All these methods are supported in the minimum version of Mac OS X which is 10.5
138139
fn proc_listpids(proc_type: u32, typeinfo: u32, buffer: *mut c_void, buffersize: u32) -> c_int;
139-
140+
fn proc_listpidspath(proc_type: u32, typeinfo: u32, path: * const c_char, pathflags: u32, buffer: *mut c_void, buffersize: u32) -> c_int;
140141
fn proc_pidinfo(pid: c_int, flavor: c_int, arg: u64, buffer: *mut c_void, buffersize: c_int) -> c_int;
141-
142142
fn proc_name(pid: c_int, buffer: *mut c_void, buffersize: u32) -> c_int;
143-
144-
fn proc_regionfilename(pid: c_int, address: u64, buffer: *mut c_void, buffersize: u32) -> c_int;
145-
143+
fn proc_libversion(major: *mut c_int, minor: *mut c_int) -> c_int;
146144
fn proc_pidpath(pid: c_int, buffer: *mut c_void, buffersize: u32) -> c_int;
145+
fn proc_regionfilename(pid: c_int, address: u64, buffer: *mut c_void, buffersize: u32) -> c_int;
147146

148-
fn proc_libversion(major: *mut c_int, minor: *mut c_int) -> c_int;
149147
}
150148

151-
152-
/// Returns the PIDs of the processes active that match the ProcType passed in
149+
/// Returns the PIDs of the active processes that match the ProcType passed in
153150
///
154151
/// # Examples
155152
///
@@ -214,6 +211,52 @@ pub fn listpids(proc_types: ProcType) -> Result<Vec<u32>, String> {
214211
}
215212
}
216213

214+
// proc_listpidspath
215+
// Search through the current processes looking for open file references which match
216+
// a specified path or volume.
217+
//
218+
// @param type types of processes to be searched (see proc_listpids)
219+
// @param typeinfo adjunct information for type
220+
// @param path file or volume path
221+
// @param pathflags flags to control which files should be considered
222+
// during the process search.
223+
// @param buffer a C array of int-sized values to be filled with
224+
// process identifiers that hold an open file reference
225+
// matching the specified path or volume. Pass NULL to
226+
// obtain the minimum buffer size needed to hold the
227+
// currently active processes.
228+
// @param buffersize the size (in bytes) of the provided buffer.
229+
// @result the number of bytes of data returned in the provided buffer;
230+
// -1 if an error was encountered;
231+
#[cfg(target_os = "macos")]
232+
pub fn listpidspath(proc_types: ProcType, path: String) -> Result<Vec<u32>, String> {
233+
let buffer_size = unsafe {
234+
proc_listpidspath(proc_types as u32, 0, path.as_ptr() as * const c_char, 0, ptr::null_mut(), 0)
235+
};
236+
if buffer_size <= 0 {
237+
return Err(helpers::get_errno_with_message(buffer_size));
238+
}
239+
240+
let capacity = buffer_size as usize / mem::size_of::<u32>();
241+
let mut pids: Vec<u32> = Vec::with_capacity(capacity);
242+
let buffer_ptr = pids.as_mut_ptr() as *mut c_void;
243+
244+
let ret = unsafe {
245+
proc_listpidspath(proc_types as u32, 0, path.as_ptr() as * const c_char, 0, buffer_ptr, buffer_size as u32)
246+
};
247+
248+
if ret <= 0 {
249+
Err(helpers::get_errno_with_message(ret))
250+
} else {
251+
let items_count = ret as usize / mem::size_of::<u32>() - 1;
252+
unsafe {
253+
pids.set_len(items_count);
254+
}
255+
256+
Ok(pids)
257+
}
258+
}
259+
217260
/// Get info about a process
218261
///
219262
/// arg - is "heavily not documented" and need to look at code for each flavour
@@ -621,9 +664,8 @@ mod test {
621664

622665
#[test]
623666
fn listpids_test() {
624-
if let Ok(pids) = listpids(ProcType::ProcAllPIDS) {
625-
assert!(pids.len() > 1);
626-
}
667+
let pids = listpids(ProcType::ProcAllPIDS).unwrap();
668+
assert!(pids.len() > 1);
627669
}
628670

629671
#[test]
@@ -699,4 +741,11 @@ mod test {
699741
assert!(procfile_field("/proc/1/status", "invalid").is_err());
700742
}
701743
}
744+
745+
#[test]
746+
#[cfg(target_os = "macos")]
747+
fn listpidspath_test() {
748+
let pids = super::listpidspath(ProcType::ProcAllPIDS, "/".into()).unwrap();
749+
assert!(pids.len() > 1);
750+
}
702751
}

0 commit comments

Comments
 (0)