Mercurial > crates > systemd-socket
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 |