//! Unix socket options that behave the same on Linux and macOS. use std::io; use std::os::unix::net::UnixStream; use std::time::Duration; /// `EINVAL` on Darwin (`sys/errno.h`); std does not name it and a crate for one number is too much. #[cfg(target_vendor = "apple")] const EINVAL: i32 = 22; /// Set the read timeout for the next read. macOS refuses every socket option with `EINVAL` once /// the peer has closed (XNU `sosetoptlock`: both `SS_CANTRCVMORE` and `SS_CANTSENDMORE` set), even /// with unread data still buffered. A read on such a socket returns that data or the end at once /// and cannot block, so there is no timeout left to set and the refusal is not an error. pub fn set_read_timeout(stream: &UnixStream, timeout: Duration) -> io::Result<()> { match stream.set_read_timeout(Some(timeout)) { #[cfg(target_vendor = "apple")] Err(e) if e.raw_os_error() == Some(EINVAL) => Ok(()), other => other, } }