diff --git a/crates/shim/src/publisher.rs b/crates/shim/src/publisher.rs index 51e66ea..2ba8001 100644 --- a/crates/shim/src/publisher.rs +++ b/crates/shim/src/publisher.rs @@ -16,7 +16,6 @@ //! Implements a client to publish events from the shim back to containerd. -use std::os::unix::io::RawFd; use std::time::{SystemTime, UNIX_EPOCH}; use containerd_shim_client as client; @@ -38,18 +37,22 @@ pub struct RemotePublisher { impl RemotePublisher { /// Connect to containerd's TTRPC endpoint. + /// /// containerd uses `/run/containerd/containerd.sock.ttrpc` by default pub fn new(address: impl AsRef) -> Result { - let fd = Self::connect(address)?; - let client = Client::new(fd); + let client = Self::connect(address)?; Ok(RemotePublisher { client: EventsClient::new(client), }) } - fn connect(address: impl AsRef) -> Result { + fn connect(address: impl AsRef) -> Result { use nix::sys::socket::*; + use nix::unistd::close; + + let unix_addr = UnixAddr::new(address.as_ref())?; + let sock_addr = SockAddr::Unix(unix_addr); // SOCK_CLOEXEC flag is Linux specific #[cfg(target_os = "linux")] @@ -65,18 +68,23 @@ impl RemotePublisher { #[cfg(not(target_os = "linux"))] { use nix::fcntl::{fcntl, FcntlArg, FdFlag}; - fcntl(fd, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC))?; + fcntl(fd, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC)).map_err(|e| { + let _ = close(fd); + e + })?; } - let unix_addr = UnixAddr::new(address.as_ref())?; - let sock_addr = SockAddr::Unix(unix_addr); + connect(fd, &sock_addr).map_err(|e| { + let _ = close(fd); + e + })?; - connect(fd, &sock_addr)?; - - Ok(fd) + // Client::new() takes ownership of the RawFd. + Ok(Client::new(fd)) } - /// Publish new event. + /// Publish a new event. + /// /// Event object can be anything that Protobuf able serialize (e.g. implement `Message` trait). pub fn publish( &self,