// SPDX-License-Identifier: MIT OR Apache-2.0 // Copyright 2020, Alyssa Ross use bincode::{DefaultOptions, Deserializer, Serializer}; use std::io::IoSlice; use std::marker::PhantomData; use std::os::unix::prelude::*; use sys_util::{net::UnixSeqpacket, ScmSocket}; use crate::{de, DeserializeWithFds, Error, Fd, FdSerializerImpl, SerializeWithFds}; /// A Unix **SOCK_SEQPACKET** socket that can send and receive values /// consisting of binary data and file descriptors. #[derive(Debug)] pub struct Socket { sock: UnixSeqpacket, __: PhantomData<(Send, Recv)>, } impl Socket { pub fn new(sock: UnixSeqpacket) -> Self { Self { sock, __: PhantomData, } } } impl Socket { pub fn send(&self, value: Send) -> Result<(), Error> { let mut bytes: Vec = vec![]; let mut fds: Vec = vec![]; value.serialize(&mut Serializer::new(&mut bytes, DefaultOptions::new()))?; value .serialize_fds(&mut FdSerializerImpl { fds: &mut fds }) .unwrap(); self.sock.send_with_fds(&[IoSlice::new(&bytes)], &fds)?; Ok(()) } } impl DeserializeWithFds<'de>> Socket { pub fn recv(&self) -> Result { let (bytes, raw_fds) = self.sock.recv_as_vec_with_fds()?; // Safe because we just received ownership of the fds. let mut fds = raw_fds.into_iter().map(|fd| unsafe { Fd::new(fd) }); let mut deserializer = Deserializer::from_slice(&bytes, DefaultOptions::new()); let deserializer_with_fds = de::WithFds { inner: &mut deserializer, fds: &mut fds, }; Ok(Recv::deserialize(deserializer_with_fds)?) } } impl AsRawFd for Socket { fn as_raw_fd(&self) -> RawFd { self.sock.as_raw_fd() } }