pub struct ProcConnector { /* private fields */ }Expand description
A safe handle to a Linux Netlink Proc Connector socket.
The socket is created, bound, and subscribed in new(). On drop, the
subscription is cancelled and the file descriptor is closed automatically.
§Examples
use proc_connector::ProcConnector;
let conn = ProcConnector::new().unwrap();
let mut buf = vec![0u8; 4096];
loop {
match conn.recv(&mut buf) {
Ok(event) => println!("got event: {event:?}"),
Err(e) => eprintln!("error: {e}"),
}
}Implementations§
Source§impl ProcConnector
impl ProcConnector
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Create a new ProcConnector.
This is a convenience constructor that:
- Creates a
PF_NETLINK/SOCK_DGRAMsocket of familyNETLINK_CONNECTOR. - Binds to the
CN_IDX_PROCmulticast group. - Sends a
PROC_CN_MCAST_LISTENsubscription message.
§Errors
Returns Error::Os if any system call fails.
Sourcepub fn subscribe(&self) -> Result<()>
pub fn subscribe(&self) -> Result<()>
(Re-)subscribe to process events.
Sends a PROC_CN_MCAST_LISTEN message via the netlink socket.
This is safe to call multiple times (e.g. after a reconnection).
§Example
let mut conn = ProcConnector::new().unwrap();
conn.subscribe().expect("subscribe");Sourcepub fn subscribe_filtered(&self, mask: EventMask) -> Result<()>
pub fn subscribe_filtered(&self, mask: EventMask) -> Result<()>
Subscribe to process events, filtering by event type mask.
mask is a bitmask of PROC_EVENT_* values (use EventMask
constants or bitwise OR). On kernels that do not support filtering
the mask is silently ignored and all events are received.
§Example
use proc_connector::{ProcConnector, EventMask};
let conn = ProcConnector::new().unwrap();
conn.subscribe_filtered(EventMask::EXEC | EventMask::EXIT)
.expect("subscribe");Sourcepub fn unsubscribe(&self) -> Result<()>
pub fn unsubscribe(&self) -> Result<()>
Unsubscribe from process events.
Sends a PROC_CN_MCAST_IGNORE message. Automatically called on drop.
§Example
let conn = ProcConnector::new().unwrap();
conn.unsubscribe().expect("unsubscribe");
// Re-subscribe later:
conn.subscribe().expect("re-subscribe");Sourcepub fn recv_raw(&self, buf: &mut [u8]) -> Result<usize>
pub fn recv_raw(&self, buf: &mut [u8]) -> Result<usize>
Receive a raw netlink message into buf.
On success returns the number of bytes written to buf.
This is a thin wrapper around recv(2). The caller is responsible
for providing a sufficiently large buffer (a page size, 4096 bytes,
is a safe default).
§Errors
InterruptedifEINTR— retry the call.ConnectionClosedif recv returns 0.Osfor other system call errors.
§Example
use proc_connector::ProcConnector;
let conn = ProcConnector::new().unwrap();
let mut buf = vec![0u8; 4096];
let n = conn.recv_raw(&mut buf).unwrap();
println!("received {n} bytes");Sourcepub fn recv_raw_timeout(
&self,
buf: &mut [u8],
timeout: Duration,
) -> Result<Option<usize>>
pub fn recv_raw_timeout( &self, buf: &mut [u8], timeout: Duration, ) -> Result<Option<usize>>
Receive a raw netlink message with a timeout.
Returns Ok(None) if the timeout expires before data is available.
Otherwise behaves the same as recv_raw.
Uses poll(2) internally and only calls recv when data is ready.
§Example
let conn = ProcConnector::new().unwrap();
let mut buf = vec![0u8; 4096];
match conn.recv_timeout(&mut buf, Duration::from_secs(5)) {
Ok(Some(event)) => println!("{event}"),
Ok(None) => eprintln!("timeout, no event in 5s"),
Err(e) => eprintln!("error: {e}"),
}Sourcepub fn recv(&self, buf: &mut [u8]) -> Result<ProcEvent>
pub fn recv(&self, buf: &mut [u8]) -> Result<ProcEvent>
Receive and parse the next process event.
buf is the receive buffer provided by the caller (allocation control).
A buffer of at least 4096 bytes (one page) is recommended.
This method handles all netlink control messages internally:
NLMSG_NOOP→ silently skipped, continue readingNLMSG_DONE(with no payload) → silently skipped, continue reading (The kernel connector protocol usesNLMSG_DONEwith a cn_msg payload for data messages, which are parsed as events.)NLMSG_ERROR(non-zero) → returned asErr(Os(...))NLMSG_OVERRUN→ returned asErr(Overrun)- Valid data → parsed into
ProcEvent
§Errors
See Self::recv_raw for system-level errors.
Additionally returns BufferTooSmall if the buffer is too small
to hold even a single netlink header.
§Example
use proc_connector::ProcConnector;
let conn = ProcConnector::new().unwrap();
let mut buf = [0u8; 4096];
loop {
match conn.recv(&mut buf) {
Ok(event) => println!("{event}"),
Err(e) => { eprintln!("{e}"); break; }
}
}Sourcepub fn recv_timeout(
&self,
buf: &mut [u8],
timeout: Duration,
) -> Result<Option<ProcEvent>>
pub fn recv_timeout( &self, buf: &mut [u8], timeout: Duration, ) -> Result<Option<ProcEvent>>
Receive and parse the next process event with a timeout.
Returns Ok(None) if the timeout expires before an event is available.
Unlike recv(), this method returns Ok(None) on timeout instead of
blocking indefinitely. It properly loops past netlink control messages
(NLMSG_NOOP, NLMSG_DONE, NLMSG_ERROR-ACK) just like recv() does.
§Errors
See Self::recv_timeout for system-level errors.
Sourcepub fn as_raw_fd(&self) -> RawFd
pub fn as_raw_fd(&self) -> RawFd
Expose the raw file descriptor for integration with async runtimes
(tokio::AsyncFd, mio, etc.).
The returned RawFd remains valid for the lifetime of this
ProcConnector. Do not close it manually.
Sourcepub fn set_recv_buf_size(&self, bytes: usize) -> Result<()>
pub fn set_recv_buf_size(&self, bytes: usize) -> Result<()>
Set the socket receive buffer size (SO_RCVBUF).
Larger buffers reduce the risk of event loss under load. Typical values range from 64 KiB to 1 MiB.
§Errors
Returns Error::Os if setsockopt(2) fails.
Sourcepub fn set_nonblocking(&self) -> Result<()>
pub fn set_nonblocking(&self) -> Result<()>
Set the socket to non-blocking mode.
After calling this, recv_raw will return Error::WouldBlock
when no data is available, instead of blocking.
§Errors
Returns Error::Os if fcntl(2) fails.
§Example
use proc_connector::{ProcConnector, Error};
let conn = ProcConnector::new().unwrap();
conn.set_nonblocking().unwrap();
let mut buf = vec![0u8; 4096];
match conn.recv_raw(&mut buf) {
Ok(n) => println!("received {n} bytes"),
Err(Error::WouldBlock) => println!("no data available"),
Err(e) => eprintln!("error: {e}"),
}