diff options
Diffstat (limited to 'msg_socket2/src/ser.rs')
-rw-r--r-- | msg_socket2/src/ser.rs | 147 |
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> { |