summary refs log tree commit diff
path: root/msg_socket2/src/de.rs
diff options
context:
space:
mode:
Diffstat (limited to 'msg_socket2/src/de.rs')
-rw-r--r--msg_socket2/src/de.rs731
1 files changed, 720 insertions, 11 deletions
diff --git a/msg_socket2/src/de.rs b/msg_socket2/src/de.rs
index 1d3a9e1..0dec746 100644
--- a/msg_socket2/src/de.rs
+++ b/msg_socket2/src/de.rs
@@ -1,21 +1,730 @@
-use serde::Deserializer;
-use std::os::unix::prelude::*;
+// SPDX-License-Identifier: MIT OR Apache-2.0
+// Copyright 2020, Alyssa Ross
+//
+// Portions Copyright Erick Tryzelaar and David Tolnay.
+// Licensed under either of Apache License, Version 2.0
+// or MIT license at your option.
 
+//! Data structure deserialization framework for Unix domain sockets.
+//!
+//! Much like `serde::de`, except receiving file descriptors is also
+//! supported.
+
+use crate::Fd;
+use std::cmp::min;
+use std::collections::BTreeMap;
+use std::fmt::{self, Formatter};
+use std::marker::PhantomData;
+
+pub use serde::de::{
+    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, SeqAccess, StdError,
+    VariantAccess, Visitor,
+};
+
+/// A generic container for an inner serde type, and some file descriptors.
+///
+/// Useful for implementing assorted `*WithFds` traits in terms of
+/// their serde equivalents.
+#[derive(Debug)]
+pub(crate) struct WithFds<'fds, T, F> {
+    pub inner: T,
+    pub fds: &'fds mut F,
+}
+
+/// Like `Deserialize`, but provides file descriptors as well as data.
 pub trait DeserializeWithFds<'de>: Sized {
-    fn deserialize<I, De>(deserializer: DeserializerWithFds<I, De>) -> Result<Self, De::Error>
+    /// Like `Deserialize::deserialize`, but `deserializer` is a
+    /// `DeserializerWithFds` instead of a `Deserializer`.
+    fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error>;
+}
+
+/// Like `DeserializeSeed`, but provides file descriptors as well as
+/// data.
+pub trait DeserializeWithFdsSeed<'de>: Sized {
+    /// Like `DeserializeSeed::Value`.
+    type Value;
+
+    /// Like `DeserializeSeed::deserialize`, but `deserializer` is a
+    /// `DeserializerWithFds` instead of a `Deserializer`.
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: DeserializerWithFds<'de>;
+}
+
+impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFdsSeed<'de> for PhantomData<T> {
+    type Value = T;
+
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: DeserializerWithFds<'de>,
+    {
+        T::deserialize(deserializer)
+    }
+}
+
+impl<'fds, 'de, T, F> DeserializeSeed<'de> for WithFds<'fds, T, F>
+where
+    F: Iterator<Item = Fd>,
+    T: DeserializeWithFdsSeed<'de>,
+{
+    type Value = T::Value;
+
+    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+        let deserializer_with_fds = WithFds {
+            inner: deserializer,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize(deserializer_with_fds)
+    }
+}
+
+/// Like `Deserializer` but provides file descriptors as well as data.
+pub trait DeserializerWithFds<'de> {
+    /// Like `Deserializer::Error`.
+    type Error: Error;
+
+    /// Deserialize a file descriptor.
+    fn deserialize_fd(self) -> Result<Fd, Self::Error>;
+
+    /// Like `Deserializer::deserialize_option`, but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
     where
-        I: Iterator<Item = RawFd>,
-        De: Deserializer<'de>;
+        V: VisitorWithFds<'de>;
+
+    /// Like `Deserializer::deserialize_seq` but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_seq<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+
+    /// Like `Deserializer::deserialize_map` but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_tuple_struct<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        len: usize,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>;
+
+    /// Like `Deserializer::deserialize_map` but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_map<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+
+    /// Like `Deserializer::deserialize_struct` but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_struct<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>;
+
+    /// Like `Deserializer::deserialize_enum` but `visitor` is a
+    /// `VisitorWithFds` instead of a `Visitor`.
+    fn deserialize_enum<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        variants: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>;
+
+    /// Invite a `Visitor` to visit a `Some` value.
+    ///
+    /// The purpose of this indirection is to allow implementations to
+    /// control how `Visitor::visit_some` is called.  This means that
+    /// whatever way they get a `Deserializer` to pass to it doesn't
+    /// have to be exposed publicly through the trait.
+    ///
+    /// This looks a lot like a `deserialize_*` method, but it takes a
+    /// `Visitor` instead of a `VisitorWithFds`, and it's not part of
+    /// the serde interface.
+    fn invite_visit_some<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+
+    /// Invite a `Deserialize` to deserialize.
+    ///
+    /// The purpose of this indirection is to allow implementations to
+    /// control how `Deserialize::deserialize` is called.  This means
+    /// that whatever way they get a `Deserializer` to pass to it
+    /// doesn't have to be exposed publicly through the trait.
+    fn invite_deserialize<T: Deserialize<'de>>(self) -> Result<T, Self::Error>;
+}
+
+impl<'fds, 'de, D, F> DeserializerWithFds<'de> for WithFds<'fds, D, F>
+where
+    D: Deserializer<'de>,
+    F: Iterator<Item = Fd>,
+{
+    type Error = D::Error;
+
+    fn deserialize_fd(self) -> Result<Fd, Self::Error> {
+        struct UnitVisitor;
+
+        impl<'de> Visitor<'de> for UnitVisitor {
+            type Value = ();
+
+            fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+                write!(f, "expecting unit")
+            }
+
+            fn visit_unit<E>(self) -> Result<Self::Value, E> {
+                Ok(())
+            }
+        }
+
+        // This is probably not necessary, since unit should be
+        // serialized to nothing, but it's more correct to do this,
+        // because unit was serialized, and so unit should be
+        // deserialized.
+        self.inner.deserialize_unit(UnitVisitor)?;
+
+        self.fds
+            .next()
+            .ok_or_else(|| Self::Error::custom("no fds to deserialize"))
+    }
+
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: VisitorWithFds<'de>,
+    {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_option(wrapper)
+    }
+
+    fn deserialize_seq<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_seq(wrapper)
+    }
+
+    fn deserialize_tuple_struct<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        len: usize,
+        visitor: V,
+    ) -> Result<V::Value, D::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_tuple_struct(name, len, wrapper)
+    }
+
+    fn deserialize_map<V: VisitorWithFds<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_map(wrapper)
+    }
+
+    fn deserialize_struct<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, D::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_struct(name, fields, wrapper)
+    }
+
+    fn deserialize_enum<V: VisitorWithFds<'de>>(
+        self,
+        name: &'static str,
+        variants: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, D::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.deserialize_enum(name, variants, wrapper)
+    }
+
+    fn invite_visit_some<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, D::Error> {
+        visitor.visit_some(self.inner)
+    }
+
+    fn invite_deserialize<T: Deserialize<'de>>(self) -> Result<T, D::Error> {
+        T::deserialize(self.inner)
+    }
 }
 
+/// A type implementing `Visitor` without any overrides.
+///
+/// This allows for referring to the default serde implementation of
+/// the `Visitor` methods from our own overrides.
 #[derive(Debug)]
-pub struct DeserializerWithFds<'iter, Iter, De> {
-    pub deserializer: De,
-    pub fds: &'iter mut Iter,
+struct VisitorDefaults<'a, V>(PhantomData<&'a V>);
+
+impl<'a, 'de, V> Visitor<'de> for VisitorDefaults<'a, V> {
+    type Value = V;
+
+    fn expecting(&self, _: &mut Formatter) -> fmt::Result {
+        unreachable!()
+    }
+}
+
+/// Like `SeqAccess`, but elements provide access to file descriptors
+/// as well as data.
+pub trait SeqAccessWithFds<'de> {
+    /// Like `SeqAccess::Error`.
+    type Error: Error;
+
+    /// Like `SeqAccess::next_element_seed`, but `seed` is a
+    /// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
+    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+    where
+        T: DeserializeWithFdsSeed<'de>;
+
+    /// Like `SeqAccess::next_element`, but returns a
+    /// `DeserializeWithFds` instead of a `Deserialize`.
+    fn next_element<T: DeserializeWithFds<'de>>(&mut self) -> Result<Option<T>, Self::Error> {
+        self.next_element_seed(PhantomData)
+    }
+
+    /// See `SeqAccess::size_hint`.
+    fn size_hint(&self) -> Option<usize> {
+        None
+    }
+
+    /// Invite a `Visitor` to visit.  The inverse of `Visitor::visit`.
+    ///
+    /// The purpose of this indirection is to allow implementations to
+    /// control how `Visitor::visit_seq` is called.  This means that
+    /// whatever way they get a `SeqAccess` to pass to it doesn't have
+    /// to be exposed publicly through the trait.
+    fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+}
+
+impl<'de, 'fds, A, F> SeqAccessWithFds<'de> for WithFds<'fds, A, F>
+where
+    A: SeqAccess<'de>,
+    F: Iterator<Item = Fd>,
+{
+    type Error = A::Error;
+
+    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+    where
+        T: DeserializeWithFdsSeed<'de>,
+    {
+        let wrapper = WithFds {
+            inner: seed,
+            fds: self.fds,
+        };
+
+        self.inner.next_element_seed(wrapper)
+    }
+
+    fn size_hint(&self) -> Option<usize> {
+        self.inner.size_hint()
+    }
+
+    fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+        visitor.visit_seq(self.inner)
+    }
 }
 
-impl<'iter, Iter, De> DeserializerWithFds<'iter, Iter, De> {
-    pub fn new(fds: &'iter mut Iter, deserializer: De) -> Self {
-        Self { deserializer, fds }
+/// Like `MapAccess`, but keys and values provide access to file
+/// descriptors as well as data.
+pub trait MapAccessWithFds<'de>: Sized {
+    /// Like `MapAccess::Error`.
+    type Error: Error;
+
+    /// Like `MapAccess::next_key_seed`, but `seed` is a
+    /// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
+    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+    where
+        K: DeserializeWithFdsSeed<'de>;
+
+    /// Like `MapAccess::next_value_seed`, but `seed` is a
+    /// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
+    fn next_value_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>, Self::Error>
+    where
+        V: DeserializeWithFdsSeed<'de>;
+
+    /// Like `MapAccess::next_entry_seed`, but `kseed` and `vseed` are
+    /// `DeserializeWithFdsSeed` instead of `DeserializeSeed`.
+    fn next_entry_seed<K: DeserializeWithFdsSeed<'de>, V: DeserializeWithFdsSeed<'de>>(
+        &mut self,
+        kseed: K,
+        vseed: V,
+    ) -> Result<Option<(K::Value, V::Value)>, Self::Error>;
+
+    /// Like `MapAccess::next_key`, but returns a `DeserializeWithFds`
+    /// instead of a `Deserialize`.
+    fn next_key<K: DeserializeWithFds<'de>>(&mut self) -> Result<Option<K>, Self::Error> {
+        self.next_key_seed(PhantomData)
+    }
+
+    /// Like `MapAccess::next_value`, but returns a `DeserializeWithFds`
+    /// instead of a `Deserialize`.
+    fn next_value<K: DeserializeWithFds<'de>>(&mut self) -> Result<Option<K>, Self::Error> {
+        self.next_value_seed(PhantomData)
+    }
+
+    /// Like `MapAccess:next_entry`, but return values are
+    /// `DeserializeWithFds` instead of `Deserialize`.
+    fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
+    where
+        K: DeserializeWithFds<'de>,
+        V: DeserializeWithFds<'de>,
+    {
+        self.next_entry_seed(PhantomData, PhantomData)
+    }
+
+    /// Like `MapAccess::size_hint`.
+    fn size_hint(&self) -> Option<usize> {
+        None
+    }
+
+    /// Invite a `Visitor` to visit.  The inverse of `Visitor::visit`.
+    ///
+    /// The purpose of this indirection is to allow implementations to
+    /// control how `Visitor::visit_map` is called.  This means that
+    /// whatever way they get a `MapAccess` to pass to it doesn't have
+    /// to be exposed publicly through the trait.
+    fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+}
+
+/// Like `EnumAccess`, but variants provide access to file descriptors
+/// as well as data.
+pub trait EnumAccessWithFds<'de>: Sized {
+    /// Like `EnumAccess::Error`.
+    type Error: Error;
+
+    /// Like `EnumAccess::Variant`, but also provides access to file
+    /// descriptors.
+    type Variant: VariantAccessWithFds<'de, Error = Self::Error>;
+
+    /// Like `EnumAccess::variant_seed`, but `seed` is a
+    /// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
+    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+    where
+        V: DeserializeSeed<'de>;
+
+    /// Like `EnumAccess::variant`, but returns a `DeserializeWithFds`
+    /// instead of a `Deserialize`.
+    fn variant<V>(self) -> Result<(V, Self::Variant), Self::Error>
+    where
+        V: Deserialize<'de>,
+    {
+        self.variant_seed(PhantomData)
+    }
+
+    /// Invite a `Visitor` to visit.  The inverse of `Visitor::visit`.
+    ///
+    /// The purpose of this indirection is to allow implementations to
+    /// control how `Visitor::visit_enum` is called.  This means that
+    /// whatever way they get an `EnumAccess` to pass to it doesn't
+    /// have to be exposed publicly through the trait.
+    fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error>;
+}
+
+impl<'fds, 'de, A, F> EnumAccessWithFds<'de> for WithFds<'fds, A, F>
+where
+    A: EnumAccess<'de>,
+    F: Iterator<Item = Fd>,
+{
+    type Error = A::Error;
+    type Variant = WithFds<'fds, A::Variant, F>;
+
+    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+    where
+        V: DeserializeSeed<'de>,
+    {
+        let (value, variant) = self.inner.variant_seed(seed)?;
+        let variant_with_fds = WithFds {
+            inner: variant,
+            fds: self.fds,
+        };
+
+        Ok((value, variant_with_fds))
+    }
+
+    fn invite<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+        visitor.visit_enum(self.inner)
+    }
+}
+
+/// Like `VariantAccess`, but provides file descriptors as well as data.
+pub trait VariantAccessWithFds<'de>: Sized {
+    /// Like `VariantAccess::Error`.
+    type Error: Error;
+
+    /// Like `VariantAccess::unit_variant`.
+    fn unit_variant(self) -> Result<(), Self::Error>;
+
+    /// Like `VariantAccess::newtype_variant_seed`, but `seed` is a
+    /// `DeserializeWithFdsSeed` instead of a `DeserializeSeed`.
+    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
+    where
+        T: DeserializeWithFdsSeed<'de>;
+
+    /// Like `VariantAccess::newtype_variant`, but returns a
+    /// `DeserializeWithFds` instead of a `Deserialize`.
+    fn newtype_variant<T: DeserializeWithFds<'de>>(self) -> Result<T, Self::Error> {
+        self.newtype_variant_seed(PhantomData)
+    }
+
+    /// Like `VariantAccess::struct_variant`, but returns a
+    /// `DeserializeWithFds` instead of a `Deserialize`.
+    fn struct_variant<V: VisitorWithFds<'de>>(
+        self,
+        fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>;
+}
+
+impl<'de, 'fds, A, F> VariantAccessWithFds<'de> for WithFds<'fds, A, F>
+where
+    A: VariantAccess<'de>,
+    F: Iterator<Item = Fd>,
+{
+    type Error = A::Error;
+
+    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
+    where
+        T: DeserializeWithFdsSeed<'de>,
+    {
+        let wrapper = WithFds {
+            inner: seed,
+            fds: self.fds,
+        };
+
+        self.inner.newtype_variant_seed(wrapper)
+    }
+
+    fn unit_variant(self) -> Result<(), Self::Error> {
+        self.inner.unit_variant()
+    }
+
+    fn struct_variant<V: VisitorWithFds<'de>>(
+        self,
+        fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error> {
+        let wrapper = WithFds {
+            inner: visitor,
+            fds: self.fds,
+        };
+
+        self.inner.struct_variant(fields, wrapper)
+    }
+}
+
+/// Like `Visitor`, but provides file descriptors as well as data.
+pub trait VisitorWithFds<'de>: Sized {
+    /// Like `Visitor::Value`.
+    type Value;
+
+    /// Like `Visitor::expecting`.
+    fn expecting(&self, f: &mut Formatter) -> fmt::Result;
+
+    /// Like `Visitor::visit_none`.
+    fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
+        VisitorDefaults(PhantomData).visit_none()
+    }
+
+    /// Like `Visitor:::visit_some`, but `deserializer` is a
+    /// `DeserializerWithFds` instead of a `Deserializer`.
+    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: DeserializerWithFds<'de>,
+    {
+        deserializer.invite_visit_some(VisitorDefaults(PhantomData))
+    }
+
+    /// Like `Visitor::visit_seq`, but `seq` is a `SeqAccessWithFds`
+    /// instead of a `SeqAccess`.
+    fn visit_seq<A: SeqAccessWithFds<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
+        seq.invite(VisitorDefaults(PhantomData))
+    }
+
+    /// Like `Visitor::visit_map`, but `map` is a `MapAccessWithFds`
+    /// instead of a `MapAccess`.
+    fn visit_map<A: MapAccessWithFds<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
+        map.invite(VisitorDefaults(PhantomData))
+    }
+
+    /// Like `Visitor::visit_enum`, but `data` is an
+    /// `EnumAccessWithFds` instead of an `EnumAccess`.
+    fn visit_enum<A: EnumAccessWithFds<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
+        data.invite(VisitorDefaults(PhantomData))
+    }
+}
+
+impl<'de, 'fds, V, F> Visitor<'de> for WithFds<'fds, V, F>
+where
+    V: VisitorWithFds<'de>,
+    F: Iterator<Item = Fd>,
+{
+    type Value = V::Value;
+
+    fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+        self.inner.expecting(f)
+    }
+
+    fn visit_seq<A: SeqAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
+        self.inner.visit_seq(WithFds {
+            inner: data,
+            fds: self.fds,
+        })
+    }
+
+    fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
+        self.inner.visit_enum(WithFds {
+            inner: data,
+            fds: self.fds,
+        })
+    }
+}
+
+macro_rules! deserialize_impl {
+    ($type:ty) => {
+        impl<'de> DeserializeWithFds<'de> for $type {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: DeserializerWithFds<'de>,
+            {
+                deserializer.invite_deserialize()
+            }
+        }
+    };
+}
+
+macro_rules! fd_impl {
+    ($type:ty) => {
+        impl<'de> DeserializeWithFds<'de> for $type {
+            fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
+                deserializer.deserialize_fd().map(|x| x.specialize())
+            }
+        }
+    };
+}
+
+deserialize_impl!(());
+
+deserialize_impl!(u8);
+deserialize_impl!(u16);
+deserialize_impl!(u32);
+deserialize_impl!(u64);
+deserialize_impl!(usize);
+
+deserialize_impl!(String);
+deserialize_impl!(std::path::PathBuf);
+
+fd_impl!(std::fs::File);
+fd_impl!(std::net::TcpListener);
+fd_impl!(std::net::TcpStream);
+fd_impl!(std::net::UdpSocket);
+fd_impl!(std::os::unix::net::UnixDatagram);
+fd_impl!(std::os::unix::net::UnixListener);
+fd_impl!(std::os::unix::net::UnixStream);
+fd_impl!(sys_util::net::UnixSeqpacket);
+
+impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFds<'de> for Option<T> {
+    fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        struct Visitor<T>(PhantomData<T>);
+
+        impl<'de, T: DeserializeWithFds<'de>> VisitorWithFds<'de> for Visitor<T> {
+            type Value = Option<T>;
+
+            fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+                write!(f, "option")
+            }
+
+            fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
+                Ok(None)
+            }
+
+            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+            where
+                D: DeserializerWithFds<'de>,
+            {
+                T::deserialize(deserializer).map(Some)
+            }
+        }
+
+        deserializer.deserialize_option(Visitor(PhantomData))
+    }
+}
+
+impl<'de, T: DeserializeWithFds<'de>> DeserializeWithFds<'de> for Vec<T> {
+    fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        struct Visitor<T>(PhantomData<T>);
+
+        impl<'de, T: DeserializeWithFds<'de>> VisitorWithFds<'de> for Visitor<T> {
+            type Value = Vec<T>;
+
+            fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+                write!(f, "a sequence")
+            }
+
+            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+            where
+                A: SeqAccessWithFds<'de>,
+            {
+                let mut values = Vec::with_capacity(min(seq.size_hint().unwrap_or(0), 4096));
+
+                while let Some(value) = seq.next_element()? {
+                    values.push(value);
+                }
+
+                Ok(values)
+            }
+        }
+
+        deserializer.deserialize_seq(Visitor(PhantomData))
+    }
+}
+
+impl<'de, K, V> DeserializeWithFds<'de> for BTreeMap<K, V>
+where
+    K: DeserializeWithFds<'de> + Ord,
+    V: DeserializeWithFds<'de>,
+{
+    fn deserialize<D: DeserializerWithFds<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        struct Visitor<K, V>(PhantomData<(K, V)>);
+
+        impl<'de, K, V> VisitorWithFds<'de> for Visitor<K, V>
+        where
+            K: DeserializeWithFds<'de> + Ord,
+            V: DeserializeWithFds<'de>,
+        {
+            type Value = BTreeMap<K, V>;
+
+            fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+                write!(f, "a map")
+            }
+
+            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+            where
+                A: MapAccessWithFds<'de>,
+            {
+                let mut values = BTreeMap::new();
+
+                while let Some((key, value)) = map.next_entry()? {
+                    values.insert(key, value);
+                }
+
+                Ok(values)
+            }
+        }
+
+        deserializer.deserialize_map(Visitor(PhantomData))
     }
 }