Skip to content

Commit c28e396

Browse files
committed
Use bindgen for OSX bindings
Manually written library bindings turn out to be fragile in the event that the the underlying library is updated. We have no control over the user's systems, so we cannot assume that the bindings we write will remain valid forever. This change introduces bindgen to create rust bindings using headers from the system on which the package is built.
1 parent a825bec commit c28e396

File tree

12 files changed

+78
-235
lines changed

12 files changed

+78
-235
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.idea
22
target
33
Cargo.lock
4+
src/osx_libproc_bindings.rs

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ path = "src/procinfo.rs"
2929
[[bin]]
3030
name = "dmesg"
3131
path = "src/dmesg.rs"
32+
33+
[build-dependencies]
34+
bindgen = "0.53.1"

build.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#[cfg(target_os = "macos")]
2+
fn main() {
3+
let bindings = bindgen::builder()
4+
.header_contents("libproc_rs.h", "#include <libproc.h>")
5+
.generate()
6+
.expect("Failed to build libproc bindings");
7+
8+
bindings
9+
.write_to_file("src/osx_libproc_bindings.rs")
10+
.expect("Failed to write libproc bindings");
11+
}
12+
13+
#[cfg(not(target_os = "macos"))]
14+
fn main() {}

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
extern crate libc;
1010
extern crate errno;
1111

12-
pub mod libproc;
12+
pub mod libproc;
13+
#[cfg(target_os = "macos")]
14+
#[allow(warnings, missing_docs)]
15+
mod osx_libproc_bindings;

src/libproc/bsd_info.rs

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,6 @@
1-
extern crate libc;
2-
3-
use self::libc::{c_char, uid_t, gid_t};
4-
51
use crate::libproc::proc_pid::{PIDInfo, PidInfoFlavor};
6-
7-
// from http://opensource.apple.com//source/xnu/xnu-1504.7.4/bsd/sys/param.h
8-
const MAXCOMLEN : usize = 16;
9-
10-
/// Struct for BSDInfo about a process
11-
#[repr(C)]
12-
#[derive(Default)]
13-
pub struct BSDInfo {
14-
/// 64bit; emulated etc
15-
pub pbi_flags : u32,
16-
/// status
17-
pub pbi_status : u32,
18-
/// x status
19-
pub pbi_xstatus : u32,
20-
/// PID
21-
pub pbi_pid : u32,
22-
/// PPID
23-
pub pbi_ppid : u32,
24-
/// UID - User ID
25-
pub pbi_uid : uid_t,
26-
/// GID - Group ID
27-
pub pbi_gid : gid_t,
28-
/// RUID
29-
pub pbi_ruid : uid_t,
30-
/// RGID
31-
pub pbi_rgid : gid_t,
32-
/// RGID
33-
pub pbi_svuid : uid_t,
34-
/// SVUID
35-
pub pbi_svgid : gid_t,
36-
/// reserved for future use
37-
pub rfu_1 : u32,
38-
/// Comm
39-
pub pbi_comm : [c_char; MAXCOMLEN],
40-
/// empty if no name is registered
41-
pub pbi_name : [c_char; 2 * MAXCOMLEN],
42-
/// nfile - Number of files
43-
pub pbi_nfiles : u32,
44-
/// PGID
45-
pub pbi_pgid : u32,
46-
/// PJOBC
47-
pub pbi_pjobc : u32,
48-
/// controlling tty dev
49-
pub e_tdev : u32,
50-
/// tty process group id
51-
pub e_tpgid : u32,
52-
/// Nice
53-
pub pbi_nice : u32,
54-
/// Start tv sec
55-
pub pbi_start_tvsec : u64,
56-
/// Start tv micro sec
57-
pub pbi_start_tvusec : u64
58-
}
2+
pub use crate::osx_libproc_bindings::proc_bsdinfo as BSDInfo;
593

604
impl PIDInfo for BSDInfo {
615
fn flavor() -> PidInfoFlavor { PidInfoFlavor::TBSDInfo }
62-
}
6+
}

src/libproc/file_info.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,9 @@ use crate::libproc::helpers;
66
use crate::libproc::proc_pid::{ListPIDInfo, PidInfoFlavor};
77

88
#[cfg(target_os = "macos")]
9-
use self::libc::{c_int, c_void};
10-
11-
// this extern block links to the libproc library
12-
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
9+
use self::libc::c_void;
1310
#[cfg(target_os = "macos")]
14-
#[link(name = "proc", kind = "dylib")]
15-
extern {
16-
// This method is supported in the minimum version of Mac OS X which is 10.5
17-
fn proc_pidfdinfo(pid: c_int, fd: c_int, flavor: c_int, buffer: *mut c_void, buffersize: c_int) -> c_int;
18-
}
11+
use crate::osx_libproc_bindings::proc_pidfdinfo;
1912

2013
/// Flavor of Pid FileDescriptor info for different types of File Descriptors
2114
pub enum PIDFDInfoFlavor {

src/libproc/kmesg_buffer.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extern crate libc;
55
use std::str;
66

77
#[cfg(target_os = "macos")]
8-
use self::libc::{c_int, c_void};
8+
use self::libc::c_void;
99

1010
#[cfg(target_os = "linux")]
1111
use std::fs::File;
@@ -18,18 +18,8 @@ use std::sync::mpsc::Receiver;
1818
#[cfg(target_os = "linux")]
1919
use std::{thread, time};
2020

21-
// See https://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/msgbuf.h
2221
#[cfg(target_os = "macos")]
23-
const MAX_MSG_BSIZE: usize = 1024 * 1024;
24-
25-
// this extern block links to the libproc library
26-
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
27-
#[cfg(target_os = "macos")]
28-
#[link(name = "proc", kind = "dylib")]
29-
extern {
30-
// This method is supported in the minimum version of Mac OS X which is 10.5
31-
fn proc_kmsgbuf(buffer: *mut c_void, buffersize: u32) -> c_int;
32-
}
22+
use crate::osx_libproc_bindings::{MAXBSIZE as MAX_MSG_BSIZE, proc_kmsgbuf};
3323

3424
/// Get the contents of the kernel message buffer
3525
///
@@ -39,7 +29,7 @@ extern {
3929
/// See http://opensource.apple.com//source/system_cmds/system_cmds-336.6/dmesg.tproj/dmesg.c// See http://opensource.apple.com//source/system_cmds/system_cmds-336.6/dmesg.tproj/dmesg.c
4030
#[cfg(target_os = "macos")]
4131
pub fn kmsgbuf() -> Result<String, String> {
42-
let mut message_buffer: Vec<u8> = Vec::with_capacity(MAX_MSG_BSIZE);
32+
let mut message_buffer: Vec<u8> = Vec::with_capacity(MAX_MSG_BSIZE as _);
4333
let buffer_ptr = message_buffer.as_mut_ptr() as *mut c_void;
4434
let ret: i32;
4535

src/libproc/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ pub mod kmesg_buffer;
1313
/// Information about Work Queues - very MacOS specific
1414
pub mod work_queue_info;
1515
/// Information about Threads running inside processes
16+
#[cfg(target_os = "macos")]
1617
pub mod thread_info;
1718
/// Information about Tasks - very MacOS specific
19+
#[cfg(target_os = "macos")]
1820
pub mod task_info;
1921
/// BSD specific information - very MacOS specific
22+
#[cfg(target_os = "macos")]
2023
pub mod bsd_info;
2124
/// Information about Process Resource Usage - added in Mac OS X 10.9
2225
pub mod pid_rusage;
@@ -28,4 +31,4 @@ pub mod file_info;
2831
#[cfg(target_os = "macos")]
2932
pub mod net_info;
3033

31-
mod helpers;
34+
mod helpers;

src/libproc/pid_rusage.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ extern crate libc;
44
use crate::libproc::helpers;
55

66
#[cfg(target_os = "macos")]
7-
use self::libc::{c_void, c_int};
7+
use self::libc::c_void;
88

99
#[cfg(target_os = "linux")]
1010
use crate::libproc::helpers::{procfile_field, parse_memory_string};
11+
#[cfg(target_os = "macos")]
12+
use crate::osx_libproc_bindings::proc_pid_rusage;
1113

1214
/// The `PIDRUsage` trait is needed for polymorphism on pidrusage types, also abstracting flavor in order to provide
1315
/// type-guaranteed flavor correctness
@@ -34,13 +36,6 @@ pub enum PidRUsageFlavor {
3436
V4 = 4,
3537
}
3638

37-
// this extern block links to the libproc library
38-
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
39-
#[cfg(target_os = "macos")]
40-
#[link(name = "proc", kind = "dylib")]
41-
extern {
42-
fn proc_pid_rusage(pid: c_int, flavor: c_int, buffer: *mut c_void) -> c_int;
43-
}
4439

4540
/// C struct for Resource Usage Version 0
4641
#[repr(C)]
@@ -381,7 +376,7 @@ pub fn pidrusage<T: PIDRUsage>(pid : i32) -> Result<T, String> {
381376
let ret: i32;
382377

383378
unsafe {
384-
ret = proc_pid_rusage(pid, flavor, buffer_ptr);
379+
ret = proc_pid_rusage(pid, flavor, buffer_ptr as _);
385380
};
386381

387382
if ret < 0 {
@@ -427,4 +422,4 @@ mod test {
427422
let usage: RUsageInfoV0 = pidrusage(std::process::id() as i32).expect("pidrusage() failed");
428423
assert!(usage.ri_resident_size > 0, "Resident size reports 0")
429424
}
430-
}
425+
}

0 commit comments

Comments
 (0)