summary refs log tree commit diff
path: root/msg_socket2/src/ser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'msg_socket2/src/ser.rs')
-rw-r--r--msg_socket2/src/ser.rs147
1 files changed, 109 insertions, 38 deletions
diff --git a/msg_socket2/src/ser.rs b/msg_socket2/src/ser.rs
index e2b9900..07ead80 100644
--- a/msg_socket2/src/ser.rs
+++ b/msg_socket2/src/ser.rs
@@ -1,45 +1,22 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
 // Copyright 2020, Alyssa Ross
-// All rights reserved.
 //
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//     * Neither the name of the <organization> nor the
-//       names of its contributors may be used to endorse or promote products
-//       derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Portions Copyright Erick Tryzelaar and David Tolnay,
+// Portions Copyright Erick Tryzelaar and David Tolnay.
 // Licensed under either of Apache License, Version 2.0
 // or MIT license at your option.
 
 //! Data structure serialization framework for Unix domain sockets.
 //!
-//! Much like serde::ser, except sending file descriptors is also
+//! Much like `serde::ser`, except sending file descriptors is also
 //! supported.
 
-use serde::ser::*;
 use std::collections::BTreeMap;
 use std::fmt::{self, Display, Formatter};
 use std::os::unix::prelude::*;
 
 pub use serde::ser::{
-    Serialize, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTupleStruct,
-    SerializeTupleVariant, Serializer,
+    Error, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
+    SerializeTupleStruct, SerializeTupleVariant, Serializer, StdError,
 };
 
 #[derive(Debug)]
@@ -64,15 +41,21 @@ pub(crate) struct Composite<'ser, S> {
     serializer: &'ser mut S,
 }
 
-/// Returned from `SerializerWithFds::serialize_seq`.
+/// Like `SerializeSeq`, but accepts file descriptors as well as data.
 pub trait SerializeSeqFds {
+    /// Like `SerializeSeq::Ok`.
     type Ok;
+
+    /// Like `SerializeSeq::Error`.
     type Error: Error;
 
+    /// Like `SerializeSeq::serialize_element`, but `value` is a
+    /// `SerializeWithFds` instead of a `Serialize`.
     fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeSeq::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -93,15 +76,21 @@ impl<'ser, 'fds> SerializeSeqFds for Composite<'ser, FdSerializerImpl<'fds>> {
     }
 }
 
-/// Returned from `SerializerWithFds::serialize_tuple_struct`.
+/// Like `SerializeTupleStruct`, but accepts file descriptors as well as data.
 pub trait SerializeTupleStructFds {
+    /// Like `SerializeTupleStruct::Ok`.
     type Ok;
+
+    /// Like `SerializeTupleStruct::Error`.
     type Error: Error;
 
+    /// Like `SerializeTupleStruct::serialize_field`, but `value` is a
+    /// `SerializeWithFds` instead of a `Serialize`.
     fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeTupleStruct::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -122,15 +111,22 @@ impl<'ser, 'fds> SerializeTupleStructFds for Composite<'ser, FdSerializerImpl<'f
     }
 }
 
-/// Returned from `SerializerWithFds::serialize_tuple_variant`.
+/// Like `SerializeTupleVariant`, but accepts file descriptors as well
+/// as data.
 pub trait SerializeTupleVariantFds {
+    /// Like `SerializeTupleVariant::Ok`.
     type Ok;
+
+    /// Like `SerializeTupleVariant::Error`.
     type Error: Error;
 
+    /// Like `SerializeTupleVariant::serialize_field`, but `value` is
+    /// a `SerializeWithFds` instead of a `Serialize`.
     fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeTupleVariant::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -151,17 +147,24 @@ impl<'ser, 'fds> SerializeTupleVariantFds for Composite<'ser, FdSerializerImpl<'
     }
 }
 
-/// Returned from `SerializerWithFds::serialize_map`.
+/// Like `SerializeMap`, but provides file descriptors as well as data.
 pub trait SerializeMapFds {
+    /// Like `SerializeMap::Ok`.
     type Ok;
+
+    /// Like `SerializeMap::Error`.
     type Error: Error;
 
+    /// Like `SerializeMap::serialize_key`, but `key` is a `SerializeWithFds` instead of a `Serialize`.
     fn serialize_key<T: SerializeWithFds + ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>;
 
+    /// Like `SerializeMap::serialize_value`, but `value` is a `SerializeWithFds` instead of a `Serialize`.
     fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeMap::serialize_key`, but `key` and `value` are
+    /// `SerializeWithFds` instead of `Serialize`.
     fn serialize_entry<K: SerializeWithFds + ?Sized, V: SerializeWithFds + ?Sized>(
         &mut self,
         key: &K,
@@ -171,6 +174,7 @@ pub trait SerializeMapFds {
         self.serialize_value(value)
     }
 
+    /// Like `SerializeMap::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -196,20 +200,28 @@ impl<'ser, 'fds> SerializeMapFds for Composite<'ser, FdSerializerImpl<'fds>> {
     }
 }
 
-/// Returned from `SerializerWithFds::serialize_struct`.
+/// Like `SerializeStruct`, but provides file descriptors as well as
+/// data.
 pub trait SerializeStructFds {
+    /// Like `SerializeStruct::Ok`.
     type Ok;
+
+    /// Like `SerializeStruct::Error`.
     type Error: Error;
 
+    /// Like `SerializeStruct::serialize_field`, but `value` is a
+    /// `SerializeWithFds` instead of a `Serialize`.
     fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeStruct::skip_field`.
     fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
         let _ = key;
         Ok(())
     }
 
+    /// Like `SerializeStruct::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -230,20 +242,28 @@ impl<'ser, 'fds> SerializeStructFds for Composite<'ser, FdSerializerImpl<'fds>>
     }
 }
 
-/// Returned from `SerializerWithFds::serialize_struct_variant`.
+/// Like `SerializeStructVariant`, but provides file descriptors as
+/// well as data.
 pub trait SerializeStructVariantFds {
+    /// Like `SerializeStructVariant::Ok`.
     type Ok;
+
+    /// Like `SerializeStructVariant::Error`.
     type Error: Error;
 
+    /// Like `SerializeStructVariant::serialize_field`, but `key` and
+    /// `value` are `SerializeWithFds` instead of `Serialize`.
     fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `SerializeStructVariant::skip_field`.
     fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
         let _ = key;
         Ok(())
     }
 
+    /// Like `SerializeStructVariant::end`.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
@@ -264,28 +284,54 @@ impl<'ser, 'fds> SerializeStructVariantFds for Composite<'ser, FdSerializerImpl<
     }
 }
 
-/// A **data format** that can send file descriptors between Unix processes.
+/// Like `Serializer`, but accepts file descriptors instead of data.
 pub trait FdSerializer: Sized {
+    /// Like `Serializer::Ok`.
     type Ok;
+
+    /// Like `Serializer::Error`.
     type Error: Error;
 
+    /// Like `Serializer::SerializeSeq`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeSeqFds: SerializeSeqFds<Ok = Self::Ok, Error = Self::Error>;
+
+    /// Like `Serializer::SerializeTupleStruct`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeTupleStructFds: SerializeTupleStructFds<Ok = Self::Ok, Error = Self::Error>;
+
+    /// Like `Serializer::SerializeTupleVariant`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeTupleVariantFds: SerializeTupleVariantFds<Ok = Self::Ok, Error = Self::Error>;
+
+    /// Like `Serializer::SerializeMap`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeMapFds: SerializeMapFds<Ok = Self::Ok, Error = Self::Error>;
+
+    /// Like `Serializer::SerializeStruct`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeStructFds: SerializeStructFds<Ok = Self::Ok, Error = Self::Error>;
+
+    /// Like `Serializer::SerializeStructVariant`, but serializes
+    /// `SerializeWithFds` instead of `Serialize`.
     type SerializeStructVariantFds: SerializeStructVariantFds<Ok = Self::Ok, Error = Self::Error>;
 
+    /// Serialize a file descriptor.
     fn serialize_raw_fd(self, value: RawFd) -> Result<Self::Ok, Self::Error>;
 
+    /// Like `Serializer::serialize_none`.
     fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
 
+    /// Like `Serializer::serialize_some`, but `value` is a
+    /// `SerializeWithFds` instead of a `Serialize`.
     fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
     where
         T: SerializeWithFds + ?Sized;
 
+    /// Like `Serializer::serialize_unit`.
     fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
 
+    /// Like `Serializer::serialize_unit_variant`.
     fn serialize_unit_variant(
         self,
         name: &'static str,
@@ -293,14 +339,23 @@ pub trait FdSerializer: Sized {
         variant: &'static str,
     ) -> Result<Self::Ok, Self::Error>;
 
+    /// Like `Serializer::serialize_seq`, but returns a
+    /// `SerializeSeqFds`, which serializes file descriptors as well
+    /// as data.
     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeqFds, Self::Error>;
 
+    /// Like `Serializer::serialize_tuple_struct`, but returns a
+    /// `SerializeTupleStructFds`, which serializes file descriptors as well
+    /// as data.
     fn serialize_tuple_struct(
         self,
         name: &'static str,
         len: usize,
     ) -> Result<Self::SerializeTupleStructFds, Self::Error>;
 
+    /// Like `Serializer::serialize_tuple_variant`, but returns a
+    /// `SerializeTupleVariantFds`, which serializes file descriptors
+    /// as well as data.
     fn serialize_tuple_variant(
         self,
         name: &'static str,
@@ -309,14 +364,23 @@ pub trait FdSerializer: Sized {
         len: usize,
     ) -> Result<Self::SerializeTupleVariantFds, Self::Error>;
 
+    /// Like `Serializer::serialize_map`, but returns a
+    /// `SerializeMapFds`, which serializes file descriptors as well
+    /// as data.
     fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMapFds, Self::Error>;
 
+    /// Like `Serializer::serialize_struct`, but returns a
+    /// `SerializeStructFds`, which serializes file descriptors as
+    /// well as data.
     fn serialize_struct(
         self,
         name: &'static str,
         len: usize,
     ) -> Result<Self::SerializeStructFds, Self::Error>;
 
+    /// Like `Serializer::serialize_struct_variant`, but returns a
+    /// `SerializeStructVariantFds`, which serializes file descriptors
+    /// as well as data.
     fn serialize_struct_variant(
         self,
         name: &'static str,
@@ -416,10 +480,16 @@ impl<'ser, 'fds> FdSerializer for &'ser mut FdSerializerImpl<'fds> {
     }
 }
 
-/// A **data structure** that can be sent over a Unix domain socket.
+/// Like `Serialize`, but additionally provides the `serialize_fds` method.
 pub trait SerializeWithFds {
-    fn serialize<Ser: Serializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>;
-    fn serialize_fds<Ser: FdSerializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>;
+    /// Like `Serialize::serialize`.
+    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
+
+    /// Serialize all file descriptors associated with this value, recursively.
+    ///
+    /// In most cases, the implementation should largely mirror the
+    /// `serialize` implementation.
+    fn serialize_fds<S: FdSerializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
 }
 
 macro_rules! serialize_impl {
@@ -489,6 +559,7 @@ fd_impl!(std::os::unix::net::UnixStream);
 fd_impl!(std::process::ChildStderr);
 fd_impl!(std::process::ChildStdin);
 fd_impl!(std::process::ChildStdout);
+fd_impl!(sys_util::net::UnixSeqpacket);
 
 impl<T: SerializeWithFds> SerializeWithFds for Option<T> {
     fn serialize<Ser: Serializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> {