From b686b4c34ea96e9d8efcb5759ab5b74bd73099a7 Mon Sep 17 00:00:00 2001 From: karlri <49443488+karlri@users.noreply.github.com> Date: Mon, 16 Sep 2019 07:07:46 +0200 Subject: [PATCH] Feature uds: Add listen_uds to ServerBuilder (#43) Allows directly passing an Unix Listener instead of a path. Useful for example when running as a daemon under systemd with the systemd crate. --- CHANGES.md | 1 + actix-server/src/builder.rs | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ec9b12ca..51e019e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ * Use new `Service` trait +* Add UDS listening support to `ServerBuilder` ## [0.2.4] - 2018-11-21 diff --git a/actix-server/src/builder.rs b/actix-server/src/builder.rs index d9f809fc..a0f0c3aa 100644 --- a/actix-server/src/builder.rs +++ b/actix-server/src/builder.rs @@ -185,20 +185,41 @@ impl ServerBuilder { #[cfg(all(unix, feature = "uds"))] /// Add new unix domain service to the server. - pub fn bind_uds(mut self, name: N, addr: U, factory: F) -> io::Result + pub fn bind_uds(self, name: N, addr: U, factory: F) -> io::Result where F: ServiceFactory, N: AsRef, U: AsRef, { - use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::os::unix::net::UnixListener; - // TODO: need to do something with existing paths - let _ = std::fs::remove_file(addr.as_ref()); + // The path must not exist when we try to bind. + // Try to remove it to avoid bind error. + if let Err(e) = std::fs::remove_file(addr.as_ref()) { + // NotFound is expected and not an issue. Anything else is. + if e.kind() != std::io::ErrorKind::NotFound { + return Err(e); + } + } let lst = UnixListener::bind(addr)?; + self.listen_uds(name, lst, factory) + } + #[cfg(all(unix, feature = "uds"))] + /// Add new unix domain service to the server. + /// Useful when running as a systemd service and + /// a socket FD can be acquired using the systemd crate. + pub fn listen_uds>( + mut self, + name: N, + lst: std::os::unix::net::UnixListener, + factory: F, + ) -> io::Result + where + F: ServiceFactory, + { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; let token = self.token.next(); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); self.services.push(StreamNewService::create(