argdata/values/
fd.rs

1use byteorder::{BigEndian, ByteOrder};
2use fd;
3use std::io;
4use std::os::raw::c_int;
5use Argdata;
6use ReadError;
7use Value;
8
9/// Create an argdata value representing a file descriptor of this process.
10pub fn process_fd(fd: c_int) -> fd::Fd {
11	fd::Fd(fd)
12}
13
14/// Create an argdata value representing a file descriptor attached to the data.
15pub fn encoded_fd<T: fd::ConvertFd>(raw: u32, convert_fd: T) -> fd::EncodedFd<T> {
16	fd::EncodedFd::new(raw, convert_fd)
17}
18
19/// Create an argdata value representing an invalid file descriptor.
20pub fn invalid_fd() -> fd::InvalidFd {
21	fd::InvalidFd
22}
23
24impl<'d> Argdata<'d> for fd::Fd {
25	fn read<'a>(&'a self) -> Result<Value<'a, 'd>, ReadError>
26	where
27		'd: 'a,
28	{
29		Ok(Value::Fd(encoded_fd(self.0 as u32, &fd::Identity)))
30	}
31
32	fn serialized_length(&self) -> usize {
33		5
34	}
35
36	fn serialize(
37		&self,
38		writer: &mut io::Write,
39		fd_map: Option<&mut fd::FdMapping>,
40	) -> io::Result<()> {
41		encoded_fd(self.0 as u32, fd::Identity).serialize(writer, fd_map)
42	}
43}
44
45impl<'d, T: fd::ConvertFd> Argdata<'d> for fd::EncodedFd<T> {
46	fn read<'a>(&'a self) -> Result<Value<'a, 'd>, ReadError>
47	where
48		'd: 'a,
49	{
50		Ok(Value::Fd(encoded_fd(self.raw, &self.convert_fd)))
51	}
52
53	fn serialized_length(&self) -> usize {
54		5
55	}
56
57	fn serialize(
58		&self,
59		writer: &mut io::Write,
60		fd_map: Option<&mut fd::FdMapping>,
61	) -> io::Result<()> {
62		let raw: u32 = if let Some(fd_map) = fd_map {
63			self.convert_fd
64				.convert_fd(self.raw)
65				.ok()
66				.map_or(!0, |fd| fd_map.map(fd))
67		} else {
68			self.raw
69		};
70		let mut buf = [3, 0, 0, 0, 0];
71		BigEndian::write_u32(&mut buf[1..], raw);
72		writer.write_all(&buf)
73	}
74}
75
76impl<'d> Argdata<'d> for fd::InvalidFd {
77	fn read<'a>(&'a self) -> Result<Value<'a, 'd>, ReadError>
78	where
79		'd: 'a,
80	{
81		Ok(Value::Fd(encoded_fd(!0, &fd::NoConvert)))
82	}
83
84	fn serialized_length(&self) -> usize {
85		5
86	}
87
88	fn serialize(&self, writer: &mut io::Write, _: Option<&mut fd::FdMapping>) -> io::Result<()> {
89		writer.write_all(&[5, 0xFF, 0xFF, 0xFF, 0xFF])
90	}
91}