1use {
30 core::mem,
31 std::{
32 io::{self, Error, ErrorKind, IoSlice, IoSliceMut},
33 os::unix::{
34 io::{AsRawFd, FromRawFd, RawFd},
35 net::{AncillaryData, SocketAncillary, UnixStream},
36 },
37 process::Stdio,
38 },
39 crate::Result,
40};
41
42const RAW_FD_SIZE: usize = mem::size_of::<RawFd>();
43
44pub trait UdsxUnixStream {
51
52 fn send_streams<B, I>(&self, id: B, streams: I) -> Result<()> where B: AsRef<[u8]>, I: IntoIterator<Item=RawFd>;
64
65 fn send_ioe<B>(&self, id: B) -> Result<()> where B: AsRef<[u8]>;
73
74 unsafe fn recv_streams<B, T>(&self, id: B, count: usize) -> Result<Vec<T>> where B: AsRef<[u8]>, T: FromRawFd;
84
85 unsafe fn recv_ioe<B>(&self, id: B) -> Result<(Stdio, Stdio, Stdio)> where B: AsRef<[u8]>;
91
92}
93
94impl UdsxUnixStream for UnixStream {
95
96 fn send_streams<B, I>(&self, id: B, streams: I) -> Result<()> where B: AsRef<[u8]>, I: IntoIterator<Item=RawFd> {
97 verify_id(&id)?;
98
99 let streams: Vec<_> = streams.into_iter().collect();
100
101 let mut ancillary_buf = vec!(0; make_size_of_streams(streams.len())?);
102 let mut ancillary = SocketAncillary::new(&mut ancillary_buf);
103 if ancillary.add_fds(&streams) == false {
104 return Err(Error::new(ErrorKind::Other, __!()));
105 }
106 self.send_vectored_with_ancillary(&[IoSlice::new(id.as_ref())], &mut ancillary)?;
107
108 Ok(())
109 }
110
111 fn send_ioe<B>(&self, id: B) -> Result<()> where B: AsRef<[u8]> {
112 self.send_streams(id, [io::stdin().as_raw_fd(), io::stdout().as_raw_fd(), io::stderr().as_raw_fd()])
113 }
114
115 unsafe fn recv_streams<B, T>(&self, id: B, count: usize) -> Result<Vec<T>> where B: AsRef<[u8]>, T: FromRawFd {
116 verify_id(&id)?;
117
118 let mut ancillary_buf = vec!(0; make_size_of_streams(count)?);
119 let mut ancillary = SocketAncillary::new(&mut ancillary_buf);
120
121 let id = id.as_ref();
123 if id != {
124 let mut io_slices = vec!(0; id.len());
125 {
126 let mut io_slices = [IoSliceMut::new(&mut io_slices)];
127 self.recv_vectored_with_ancillary(&mut io_slices, &mut ancillary)?;
128 }
129 io_slices
130 } {
131 return Err(Error::new(ErrorKind::InvalidData, __!("Invalid ID of streams")));
132 }
133
134 let mut result = Vec::with_capacity(count);
135 for messages in ancillary.messages() {
136 let data = messages.map_err(|e| Error::new(ErrorKind::Other, __!("{:?}", e)))?;
137 match data {
138 AncillaryData::ScmRights(scm_rights) => scm_rights.for_each(|fd| result.push(T::from_raw_fd(fd))),
139 AncillaryData::ScmCredentials(_) => return Err(
140 Error::new(ErrorKind::InvalidData, __!("Expected ScmRights, got ScmCredentials"))
141 ),
142 };
143 }
144
145 Ok(result)
146 }
147
148 unsafe fn recv_ioe<B>(&self, id: B) -> Result<(Stdio, Stdio, Stdio)> where B: AsRef<[u8]> {
149 const COUNT: usize = 3;
150
151 let mut result = self.recv_streams::<_, Stdio>(id, COUNT)?;
152 match result.len() {
153 COUNT => Ok((result.remove(0), result.remove(0), result.remove(0))),
154 other => Err(Error::new(ErrorKind::InvalidData, __!(
155 "recv_streams() returned a vector of {other} item(s); expected: {count}", other=other, count=COUNT,
156 ))),
157 }
158 }
159
160}
161
162fn verify_id<B>(id: B) -> Result<()> where B: AsRef<[u8]> {
164 if id.as_ref().is_empty() {
165 Err(Error::new(ErrorKind::InvalidData, __!("ID must not be empty")))
166 } else {
167 Ok(())
168 }
169}
170
171fn make_size_of_streams(count: usize) -> Result<usize> {
173 const FACTOR: usize = 6;
175
176 match RAW_FD_SIZE.checked_mul(count).map(|x| x.checked_mul(FACTOR)) {
177 Some(Some(result)) => Ok(result),
178 _ => Err(Error::new(ErrorKind::InvalidData, __!("Stream has too much items: {count}", count=count))),
179 }
180}