Skip to content

Commit 9a72e77

Browse files
Merge pull request #10 from ivxvm/better-listpids
Get rid of unnecessary big vector allocation in listpids
2 parents eac2843 + 3a8927a commit 9a72e77

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

src/libproc/proc_pid.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extern crate errno;
33

44
use self::libc::{uint64_t, uint32_t, int32_t, c_void, c_int, uid_t, gid_t, c_char};
55
use self::errno::errno;
6+
use std::ptr;
67
use std::mem;
78

89
// Since we cannot access C macros for constants from Rust - I have had to redefine this, based on Apple's source code
@@ -20,15 +21,12 @@ use std::mem;
2021
const MAXPATHLEN: usize = 1024;
2122
const PROC_PIDPATHINFO_MAXSIZE: usize = 4 * MAXPATHLEN;
2223

23-
// This constant is the maximum number of PIDs we will fetch and return from listpids
24-
// from https://opensource.apple.com/source/xnu/xnu-1699.24.23/bsd/sys/proc_internal.h
25-
const PID_MAX: usize = 99999;
26-
2724
// from http://opensource.apple.com//source/xnu/xnu-1456.1.26/bsd/sys/proc_info.h
2825
const MAXTHREADNAMESIZE : usize = 64;
2926

3027
// From http://opensource.apple.com//source/xnu/xnu-1456.1.26/bsd/sys/proc_info.h and
3128
// http://fxr.watson.org/fxr/source/bsd/sys/proc_info.h?v=xnu-2050.18.24
29+
#[derive(Copy, Clone)]
3230
pub enum ProcType {
3331
ProcAllPIDS = 1,
3432
ProcPGRPOnly = 2,
@@ -229,20 +227,21 @@ pub fn get_errno_with_message(ret: i32) -> String {
229227
/// }
230228
/// ```
231229
pub fn listpids(proc_types: ProcType) -> Result<Vec<u32>, String> {
232-
let mut pids: Vec<u32> = Vec::with_capacity(PID_MAX);
233-
let buffer_ptr = pids.as_mut_ptr() as *mut c_void;
234-
let buffer_size = (pids.capacity() * 4) as u32;
235-
let ret: i32;
236-
237-
unsafe {
238-
ret = proc_listpids(proc_types as u32, 0, buffer_ptr, buffer_size);
230+
let buffer_size = unsafe { proc_listpids(proc_types as u32, 0, ptr::null_mut(), 0) };
231+
if buffer_size <= 0 {
232+
return Err(get_errno_with_message(buffer_size))
239233
}
240234

241-
let items_count = ret as usize / mem::size_of::<u32>() - 1;
235+
let capacity = buffer_size as usize / mem::size_of::<u32>();
236+
let mut pids: Vec<u32> = Vec::with_capacity(capacity);
237+
let buffer_ptr = pids.as_mut_ptr() as *mut c_void;
238+
239+
let ret = unsafe { proc_listpids(proc_types as u32, 0, buffer_ptr, buffer_size as u32) };
242240

243241
if ret <= 0 {
244242
Err(get_errno_with_message(ret))
245243
} else {
244+
let items_count = ret as usize / mem::size_of::<u32>() - 1;
246245
unsafe {
247246
pids.set_len(items_count);
248247
}

0 commit comments

Comments
 (0)