comparison src/lib.rs @ 16:bc76507dd878

Fixed conditional compilation based on OS A mistake was causing systemd to never enable and the tests were too clever to detect that. Not sure what to do with it.
author Martin Habovstiak <martin.habovstiak@gmail.com>
date Tue, 22 Dec 2020 13:58:47 +0100
parents f740dadd2948
children dfb727367934
comparison
equal deleted inserted replaced
15:08b37039504b 16:bc76507dd878
66 use std::fmt; 66 use std::fmt;
67 use std::ffi::{OsStr, OsString}; 67 use std::ffi::{OsStr, OsString};
68 use crate::error::*; 68 use crate::error::*;
69 use crate::resolv_addr::ResolvAddr; 69 use crate::resolv_addr::ResolvAddr;
70 70
71 #[cfg(not(all(linux, feature = "enable_systemd")))] 71 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
72 use std::convert::Infallible as Never; 72 use std::convert::Infallible as Never;
73 73
74 #[cfg(all(linux, feature = "enable_systemd"))] 74 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
75 pub(crate) mod systemd_sockets { 75 pub(crate) mod systemd_sockets {
76 use std::fmt; 76 use std::fmt;
77 use std::sync::Mutex; 77 use std::sync::Mutex;
78 use libsystemd::activation::FileDescriptor; 78 use libsystemd::activation::FileDescriptor;
79 use libsystemd::errors::Error as LibSystemdError; 79 use libsystemd::errors::Error as LibSystemdError;
225 225
226 // We can't impl<T: Deref<Target=str> + Into<String>> TryFrom<T> for SocketAddr because of orphan 226 // We can't impl<T: Deref<Target=str> + Into<String>> TryFrom<T> for SocketAddr because of orphan
227 // rules. 227 // rules.
228 fn try_from_generic<'a, T>(string: T) -> Result<Self, ParseError> where T: 'a + std::ops::Deref<Target=str> + Into<String> { 228 fn try_from_generic<'a, T>(string: T) -> Result<Self, ParseError> where T: 'a + std::ops::Deref<Target=str> + Into<String> {
229 if string.starts_with(SYSTEMD_PREFIX) { 229 if string.starts_with(SYSTEMD_PREFIX) {
230 #[cfg(all(linux, feature = "enable_systemd"))] 230 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
231 { 231 {
232 let name_len = string.len() - SYSTEMD_PREFIX.len(); 232 let name_len = string.len() - SYSTEMD_PREFIX.len();
233 match string[SYSTEMD_PREFIX.len()..].chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') { 233 match string[SYSTEMD_PREFIX.len()..].chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') {
234 None if name_len <= 255 => Ok(SocketAddr(SocketAddrInner::Systemd(string.into()))), 234 None if name_len <= 255 => Ok(SocketAddr(SocketAddrInner::Systemd(string.into()))),
235 None => Err(ParseErrorInner::LongSocketName { string: string.into(), len: name_len }.into()), 235 None => Err(ParseErrorInner::LongSocketName { string: string.into(), len: name_len }.into()),
236 Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: string.into(), c, pos, }.into()), 236 Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: string.into(), c, pos, }.into()),
237 } 237 }
238 } 238 }
239 #[cfg(not(all(linux, feature = "enable_systemd")))] 239 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
240 { 240 {
241 Err(ParseErrorInner::SystemdUnsupported(string.into()).into()) 241 Err(ParseErrorInner::SystemdUnsupported(string.into()).into())
242 } 242 }
243 } else { 243 } else {
244 match string.parse() { 244 match string.parse() {
246 Err(_) => Ok(SocketAddr(SocketAddrInner::WithHostname(ResolvAddr::try_from_generic(string).map_err(ParseErrorInner::ResolvAddr)?))), 246 Err(_) => Ok(SocketAddr(SocketAddrInner::WithHostname(ResolvAddr::try_from_generic(string).map_err(ParseErrorInner::ResolvAddr)?))),
247 } 247 }
248 } 248 }
249 } 249 }
250 250
251 #[cfg(all(linux, feature = "enable_systemd"))] 251 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
252 fn get_systemd(socket_name: String) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> { 252 fn get_systemd(socket_name: String) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
253 use libsystemd::activation::IsType; 253 use libsystemd::activation::IsType;
254 use std::os::unix::io::{FromRawFd, IntoRawFd}; 254 use std::os::unix::io::{FromRawFd, IntoRawFd};
255 255
256 let socket = systemd_sockets::take(&socket_name[SYSTEMD_PREFIX.len()..]).map_err(BindErrorInner::ReceiveDescriptors)?; 256 let socket = systemd_sockets::take(&socket_name[SYSTEMD_PREFIX.len()..]).map_err(BindErrorInner::ReceiveDescriptors)?;
266 } 266 }
267 } 267 }
268 } 268 }
269 269
270 // This approach makes the rest of the code much simpler as it doesn't require sprinkling it 270 // This approach makes the rest of the code much simpler as it doesn't require sprinkling it
271 // with #[cfg(all(linux, feature = "enable_systemd"))] yet still statically guarantees it won't execute. 271 // with #[cfg(all(target_os = "linux", feature = "enable_systemd"))] yet still statically guarantees it won't execute.
272 #[cfg(not(linux))] 272 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
273 fn get_systemd(socket_name: Never) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> { 273 fn get_systemd(socket_name: Never) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
274 match socket_name {} 274 match socket_name {}
275 } 275 }
276 } 276 }
277 277
298 // PartialEq for testing, I'm not convinced it should be exposed 298 // PartialEq for testing, I'm not convinced it should be exposed
299 #[derive(Debug, PartialEq)] 299 #[derive(Debug, PartialEq)]
300 enum SocketAddrInner { 300 enum SocketAddrInner {
301 Ordinary(std::net::SocketAddr), 301 Ordinary(std::net::SocketAddr),
302 WithHostname(resolv_addr::ResolvAddr), 302 WithHostname(resolv_addr::ResolvAddr),
303 #[cfg(all(linux, feature = "enable_systemd"))] 303 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
304 Systemd(String), 304 Systemd(String),
305 #[cfg(not(all(linux, feature = "enable_systemd")))] 305 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
306 #[allow(dead_code)] 306 #[allow(dead_code)]
307 Systemd(Never), 307 Systemd(Never),
308 } 308 }
309 309
310 const SYSTEMD_PREFIX: &str = "systemd://"; 310 const SYSTEMD_PREFIX: &str = "systemd://";
402 fn parse_ordinary() { 402 fn parse_ordinary() {
403 assert_eq!("127.0.0.1:42".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Ordinary(([127, 0, 0, 1], 42).into())); 403 assert_eq!("127.0.0.1:42".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Ordinary(([127, 0, 0, 1], 42).into()));
404 } 404 }
405 405
406 #[test] 406 #[test]
407 #[cfg(all(linux, feature = "enable_systemd"))] 407 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
408 fn parse_systemd() { 408 fn parse_systemd() {
409 assert_eq!("systemd://foo".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned())); 409 assert_eq!("systemd://foo".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned()));
410 } 410 }
411 411
412 #[test] 412 #[test]
413 #[cfg(not(all(linux, feature = "enable_systemd")))] 413 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
414 #[should_panic] 414 #[should_panic]
415 fn parse_systemd() { 415 fn parse_systemd() {
416 "systemd://foo".parse::<SocketAddr>().unwrap(); 416 "systemd://foo".parse::<SocketAddr>().unwrap();
417 } 417 }
418 418