ops::Sub,
};
+use nix::errno::Errno;
+
#[cfg_attr(windows, path = "list_win.rs")]
#[cfg_attr(unix, path = "list_unix.rs")]
mod list;
#[cfg_attr(windows, path = "watch_win.rs")]
#[cfg_attr(target_vendor = "apple", path = "watch_mac.rs")]
-#[cfg_attr(any(target_os = "linux", target_os = "android"), path = "watch_linux.rs")]
+#[cfg_attr(
+ any(target_os = "linux", target_os = "android"),
+ path = "watch_linux.rs"
+)]
mod watch;
type IfIndex = u32;
/// Errors in netwatcher or in one of the underlying platform integratinos.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
- // TODO: handle all cases with proper sources
+ CreateSocket(Errno),
+ Bind(Errno),
+ CreatePipe(Errno),
+ Getifaddrs(Errno),
+ GetInterfaceName(Errno),
+ FormatMacAddress,
Internal,
}
}
pub(crate) fn list_interfaces() -> Result<List, Error> {
- let addrs = getifaddrs().map_err(|_| Error::Internal)?;
+ let addrs = getifaddrs().map_err(|e| Error::Getifaddrs(e))?;
let mut candidates = HashMap::new();
for addr in addrs {
- let index = if_nametoindex(addr.interface_name.as_str()).map_err(|_| Error::Internal)?;
+ let index =
+ if_nametoindex(addr.interface_name.as_str()).map_err(|e| Error::GetInterfaceName(e))?;
let candidate = candidates
.entry(addr.interface_name.clone())
.or_insert_with(|| CandidateInterface {
let mut mac = String::with_capacity(bytes.len() * 3);
for (i, b) in bytes.iter().enumerate() {
if i != 0 {
- write!(mac, ":").map_err(|_| Error::Internal)?;
+ write!(mac, ":").map_err(|_| Error::FormatMacAddress)?;
}
- write!(mac, "{:02X}", b).map_err(|_| Error::Internal)?;
+ write!(mac, "{:02X}", b).map_err(|_| Error::FormatMacAddress)?;
}
Ok(mac)
}
SockFlag::empty(),
Some(SockProtocol::NetlinkRoute),
)
- .map_err(|_| Error::Internal)?; // TODO: proper errors
+ .map_err(|e| Error::CreateSocket(e))?;
+ // TODO: set nonblocking
let sa_nl = NetlinkAddr::new(
0,
(RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR) as u32,
);
- bind(sockfd.as_raw_fd(), &sa_nl).map_err(|_| Error::Internal)?; // TODO: proper errors
- let (pipe_rd, pipe_wr) = pipe().map_err(|_| Error::Internal)?;
+ bind(sockfd.as_raw_fd(), &sa_nl).map_err(|e| Error::Bind(e))?;
+ let (pipe_rd, pipe_wr) = pipe().map_err(|e| Error::CreatePipe(e))?;
let mut prev_list = List::default();
let mut handle_update = move |new_list: List| {
impl Drop for WatchHandle {
fn drop(&mut self) {
- unsafe { nw_path_monitor_cancel(self.path_monitor); }
+ unsafe {
+ nw_path_monitor_cancel(self.path_monitor);
+ }
}
}
nw_path_monitor_set_queue(path_monitor, queue);
nw_path_monitor_start(path_monitor);
}
- Ok(WatchHandle {
- path_monitor,
- })
+ Ok(WatchHandle { path_monitor })
}