diff --git a/msg_socket/Cargo.toml b/msg_socket/Cargo.toml deleted file mode 100644 index 418b311322..0000000000 --- a/msg_socket/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "msg_socket" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[dependencies] -cros_async = { path = "../cros_async" } -data_model = { path = "../data_model" } -futures = "*" -libc = "*" -msg_on_socket_derive = { path = "msg_on_socket_derive" } -base = { path = "../base" } -sync = { path = "../sync" } diff --git a/msg_socket/msg_on_socket_derive/Cargo.toml b/msg_socket/msg_on_socket_derive/Cargo.toml deleted file mode 100644 index 206c03a78f..0000000000 --- a/msg_socket/msg_on_socket_derive/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "msg_on_socket_derive" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[dependencies] -base = "*" -proc-macro2 = "^1" -quote = "^1" -syn = "^1" - -[lib] -proc-macro = true -path = "msg_on_socket_derive.rs" diff --git a/msg_socket/msg_on_socket_derive/msg_on_socket_derive.rs b/msg_socket/msg_on_socket_derive/msg_on_socket_derive.rs deleted file mode 100644 index 98b3549003..0000000000 --- a/msg_socket/msg_on_socket_derive/msg_on_socket_derive.rs +++ /dev/null @@ -1,911 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#![recursion_limit = "256"] -extern crate proc_macro; - -use std::vec::Vec; - -use proc_macro2::{Span, TokenStream}; -use quote::{format_ident, quote}; -use syn::{ - parse_macro_input, Data, DataEnum, DataStruct, DeriveInput, Fields, Ident, Index, Member, Meta, - NestedMeta, Type, -}; - -/// The function that derives the recursive implementation for struct or enum. -#[proc_macro_derive(MsgOnSocket, attributes(msg_on_socket))] -pub fn msg_on_socket_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - let impl_for_input = socket_msg_impl(input); - impl_for_input.into() -} - -fn socket_msg_impl(input: DeriveInput) -> TokenStream { - if !input.generics.params.is_empty() { - return quote! { - compile_error!("derive(SocketMsg) does not support generic parameters"); - }; - } - match input.data { - Data::Struct(ds) => { - if is_named_struct(&ds) { - impl_for_named_struct(input.ident, ds) - } else { - impl_for_tuple_struct(input.ident, ds) - } - } - Data::Enum(de) => impl_for_enum(input.ident, de), - _ => quote! { - compile_error!("derive(SocketMsg) only support struct and enum"); - }, - } -} - -fn is_named_struct(ds: &DataStruct) -> bool { - matches!(&ds.fields, Fields::Named(_f)) -} - -/************************** Named Struct Impls ********************************************/ - -struct StructField { - member: Member, - ty: Type, - skipped: bool, -} - -fn impl_for_named_struct(name: Ident, ds: DataStruct) -> TokenStream { - let fields = get_struct_fields(ds); - let uses_fd_impl = define_uses_fd_for_struct(&fields); - let buffer_sizes_impls = define_buffer_size_for_struct(&fields); - - let read_buffer = define_read_buffer_for_struct(&name, &fields); - let write_buffer = define_write_buffer_for_struct(&name, &fields); - quote! { - impl msg_socket::MsgOnSocket for #name { - #uses_fd_impl - #buffer_sizes_impls - #read_buffer - #write_buffer - } - } -} - -// Flatten struct fields. -fn get_struct_fields(ds: DataStruct) -> Vec { - let fields = match ds.fields { - Fields::Named(fields_named) => fields_named.named, - _ => { - panic!("Struct must have named fields"); - } - }; - let mut vec = Vec::new(); - for field in fields { - let member = match field.ident { - Some(ident) => Member::Named(ident), - None => panic!("Unknown Error."), - }; - let ty = field.ty; - let mut skipped = false; - for attr in field - .attrs - .iter() - .filter(|attr| attr.path.is_ident("msg_on_socket")) - { - match attr.parse_meta().unwrap() { - Meta::List(meta) => { - for nested in meta.nested { - match nested { - NestedMeta::Meta(Meta::Path(ref meta_path)) - if meta_path.is_ident("skip") => - { - skipped = true; - } - _ => panic!("unrecognized attribute meta `{}`", quote! { #nested }), - } - } - } - _ => panic!("unrecognized attribute `{}`", quote! { #attr }), - } - } - vec.push(StructField { - member, - ty, - skipped, - }); - } - vec -} - -fn define_uses_fd_for_struct(fields: &[StructField]) -> TokenStream { - let field_types: Vec<_> = fields - .iter() - .filter(|f| !f.skipped) - .map(|f| &f.ty) - .collect(); - - if field_types.is_empty() { - return quote!(); - } - - quote! { - fn uses_descriptor() -> bool { - #(<#field_types>::uses_descriptor())||* - } - } -} - -fn define_buffer_size_for_struct(fields: &[StructField]) -> TokenStream { - let (msg_size, fd_count) = get_fields_buffer_size_sum(fields); - quote! { - fn msg_size(&self) -> usize { - #msg_size - } - fn descriptor_count(&self) -> usize { - #fd_count - } - } -} - -fn define_read_buffer_for_struct(_name: &Ident, fields: &[StructField]) -> TokenStream { - let mut read_fields = Vec::new(); - let mut init_fields = Vec::new(); - for field in fields { - let ident = match &field.member { - Member::Named(ident) => ident, - Member::Unnamed(_) => unreachable!(), - }; - let name = ident.clone(); - if field.skipped { - let ty = &field.ty; - init_fields.push(quote! { - #name: <#ty>::default() - }); - continue; - } - let read_field = read_from_buffer_and_move_offset(&ident, &field.ty); - read_fields.push(read_field); - init_fields.push(quote!(#name)); - } - quote! { - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - #(#read_fields)* - Ok(( - Self { - #(#init_fields),* - }, - __fd_offset - )) - } - } -} - -fn define_write_buffer_for_struct(_name: &Ident, fields: &[StructField]) -> TokenStream { - let mut write_fields = Vec::new(); - for field in fields { - if field.skipped { - continue; - } - let ident = match &field.member { - Member::Named(ident) => ident, - Member::Unnamed(_) => unreachable!(), - }; - let write_field = write_to_buffer_and_move_offset(&ident); - write_fields.push(write_field); - } - quote! { - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - #(#write_fields)* - Ok(__fd_offset) - } - } -} - -/************************** Enum Impls ********************************************/ -fn impl_for_enum(name: Ident, de: DataEnum) -> TokenStream { - let uses_fd_impl = define_uses_fd_for_enum(&de); - let buffer_sizes_impls = define_buffer_size_for_enum(&name, &de); - let read_buffer = define_read_buffer_for_enum(&name, &de); - let write_buffer = define_write_buffer_for_enum(&name, &de); - quote! { - impl msg_socket::MsgOnSocket for #name { - #uses_fd_impl - #buffer_sizes_impls - #read_buffer - #write_buffer - } - } -} - -fn define_uses_fd_for_enum(de: &DataEnum) -> TokenStream { - let mut variant_field_types = Vec::new(); - for variant in &de.variants { - for variant_field_ty in variant.fields.iter().map(|f| &f.ty) { - variant_field_types.push(variant_field_ty); - } - } - - if variant_field_types.is_empty() { - return quote!(); - } - - quote! { - fn uses_descriptor() -> bool { - #(<#variant_field_types>::uses_descriptor())||* - } - } -} - -fn define_buffer_size_for_enum(name: &Ident, de: &DataEnum) -> TokenStream { - let mut msg_size_match_variants = Vec::new(); - let mut fd_count_match_variants = Vec::new(); - - for variant in &de.variants { - let variant_name = &variant.ident; - match &variant.fields { - Fields::Named(fields) => { - let mut tmp_names = Vec::new(); - for field in &fields.named { - tmp_names.push(field.ident.clone().unwrap()); - } - - let v = quote! { - #name::#variant_name { #(#tmp_names),* } => #(#tmp_names.msg_size())+*, - }; - msg_size_match_variants.push(v); - - let v = quote! { - #name::#variant_name { #(#tmp_names),* } => #(#tmp_names.descriptor_count())+*, - }; - fd_count_match_variants.push(v); - } - Fields::Unnamed(fields) => { - let mut tmp_names = Vec::new(); - for idx in 0..fields.unnamed.len() { - let tmp_name = format!("enum_field{}", idx); - let tmp_name = Ident::new(&tmp_name, Span::call_site()); - tmp_names.push(tmp_name.clone()); - } - - let v = quote! { - #name::#variant_name(#(#tmp_names),*) => #(#tmp_names.msg_size())+*, - }; - msg_size_match_variants.push(v); - - let v = quote! { - #name::#variant_name(#(#tmp_names),*) => #(#tmp_names.descriptor_count())+*, - }; - fd_count_match_variants.push(v); - } - Fields::Unit => { - let v = quote! { - #name::#variant_name => 0, - }; - msg_size_match_variants.push(v.clone()); - fd_count_match_variants.push(v); - } - } - } - - quote! { - fn msg_size(&self) -> usize { - 1 + match self { - #(#msg_size_match_variants)* - } - } - fn descriptor_count(&self) -> usize { - match self { - #(#fd_count_match_variants)* - } - } - } -} - -fn define_read_buffer_for_enum(name: &Ident, de: &DataEnum) -> TokenStream { - let mut match_variants = Vec::new(); - let de = de.clone(); - for (idx, variant) in de.variants.iter().enumerate() { - let idx = idx as u8; - let variant_name = &variant.ident; - match &variant.fields { - Fields::Named(fields) => { - let mut tmp_names = Vec::new(); - let mut read_tmps = Vec::new(); - for f in &fields.named { - tmp_names.push(f.ident.clone()); - let read_tmp = - read_from_buffer_and_move_offset(f.ident.as_ref().unwrap(), &f.ty); - read_tmps.push(read_tmp); - } - let v = quote! { - #idx => { - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - #(#read_tmps)* - Ok((#name::#variant_name { #(#tmp_names),* }, __fd_offset)) - } - }; - match_variants.push(v); - } - Fields::Unnamed(fields) => { - let mut tmp_names = Vec::new(); - let mut read_tmps = Vec::new(); - for (idx, field) in fields.unnamed.iter().enumerate() { - let tmp_name = format_ident!("enum_field{}", idx); - tmp_names.push(tmp_name.clone()); - let read_tmp = read_from_buffer_and_move_offset(&tmp_name, &field.ty); - read_tmps.push(read_tmp); - } - - let v = quote! { - #idx => { - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - #(#read_tmps)* - Ok((#name::#variant_name( #(#tmp_names),*), __fd_offset)) - } - }; - match_variants.push(v); - } - Fields::Unit => { - let v = quote! { - #idx => Ok((#name::#variant_name, 0)), - }; - match_variants.push(v); - } - } - } - quote! { - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let v = buffer.get(0).ok_or(msg_socket::MsgError::WrongMsgBufferSize)?; - match v { - #(#match_variants)* - _ => Err(msg_socket::MsgError::InvalidType), - } - } - } -} - -fn define_write_buffer_for_enum(name: &Ident, de: &DataEnum) -> TokenStream { - let mut match_variants = Vec::new(); - let de = de.clone(); - for (idx, variant) in de.variants.iter().enumerate() { - let idx = idx as u8; - let variant_name = &variant.ident; - match &variant.fields { - Fields::Named(fields) => { - let mut tmp_names = Vec::new(); - let mut write_tmps = Vec::new(); - for f in &fields.named { - tmp_names.push(f.ident.clone().unwrap()); - let write_tmp = - enum_write_to_buffer_and_move_offset(&f.ident.as_ref().unwrap()); - write_tmps.push(write_tmp); - } - - let v = quote! { - #name::#variant_name { #(#tmp_names),* } => { - buffer[0] = #idx; - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - #(#write_tmps)* - Ok(__fd_offset) - } - }; - match_variants.push(v); - } - Fields::Unnamed(fields) => { - let mut tmp_names = Vec::new(); - let mut write_tmps = Vec::new(); - for idx in 0..fields.unnamed.len() { - let tmp_name = format_ident!("enum_field{}", idx); - tmp_names.push(tmp_name.clone()); - let write_tmp = enum_write_to_buffer_and_move_offset(&tmp_name); - write_tmps.push(write_tmp); - } - - let v = quote! { - #name::#variant_name(#(#tmp_names),*) => { - buffer[0] = #idx; - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - #(#write_tmps)* - Ok(__fd_offset) - } - }; - match_variants.push(v); - } - Fields::Unit => { - let v = quote! { - #name::#variant_name => { - buffer[0] = #idx; - Ok(0) - } - }; - match_variants.push(v); - } - } - } - - quote! { - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - if buffer.is_empty() { - return Err(msg_socket::MsgError::WrongMsgBufferSize) - } - match self { - #(#match_variants)* - } - } - } -} - -fn enum_write_to_buffer_and_move_offset(name: &Ident) -> TokenStream { - quote! { - let o = #name.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += #name.msg_size(); - __fd_offset += o; - } -} - -/************************** Tuple Impls ********************************************/ -fn impl_for_tuple_struct(name: Ident, ds: DataStruct) -> TokenStream { - let fields = get_tuple_fields(ds); - - let uses_fd_impl = define_uses_fd_for_tuples(&fields); - let buffer_sizes_impls = define_buffer_size_for_struct(&fields); - let read_buffer = define_read_buffer_for_tuples(&name, &fields); - let write_buffer = define_write_buffer_for_tuples(&name, &fields); - quote! { - impl msg_socket::MsgOnSocket for #name { - #uses_fd_impl - #buffer_sizes_impls - #read_buffer - #write_buffer - } - } -} - -fn get_tuple_fields(ds: DataStruct) -> Vec { - let mut field_idents = Vec::new(); - let fields = match ds.fields { - Fields::Unnamed(fields_unnamed) => fields_unnamed.unnamed, - _ => { - panic!("Tuple struct must have unnamed fields."); - } - }; - for (idx, field) in fields.iter().enumerate() { - let member = Member::Unnamed(Index::from(idx)); - let ty = field.ty.clone(); - field_idents.push(StructField { - member, - ty, - skipped: false, - }); - } - field_idents -} - -fn define_uses_fd_for_tuples(fields: &[StructField]) -> TokenStream { - if fields.is_empty() { - return quote!(); - } - - let field_types = fields.iter().map(|f| &f.ty); - quote! { - fn uses_descriptor() -> bool { - #(<#field_types>::uses_descriptor())||* - } - } -} - -fn define_read_buffer_for_tuples(name: &Ident, fields: &[StructField]) -> TokenStream { - let mut read_fields = Vec::new(); - let mut init_fields = Vec::new(); - for (idx, field) in fields.iter().enumerate() { - let tmp_name = format!("tuple_tmp{}", idx); - let tmp_name = Ident::new(&tmp_name, Span::call_site()); - let read_field = read_from_buffer_and_move_offset(&tmp_name, &field.ty); - read_fields.push(read_field); - init_fields.push(quote!(#tmp_name)); - } - - quote! { - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - #(#read_fields)* - Ok(( - #name ( - #(#init_fields),* - ), - __fd_offset - )) - } - } -} - -fn define_write_buffer_for_tuples(name: &Ident, fields: &[StructField]) -> TokenStream { - let mut write_fields = Vec::new(); - let mut tmp_names = Vec::new(); - for idx in 0..fields.len() { - let tmp_name = format_ident!("tuple_tmp{}", idx); - let write_field = enum_write_to_buffer_and_move_offset(&tmp_name); - write_fields.push(write_field); - tmp_names.push(tmp_name); - } - quote! { - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - let #name( #(#tmp_names),* ) = self; - #(#write_fields)* - Ok(__fd_offset) - } - } -} -/************************** Helpers ********************************************/ -fn get_fields_buffer_size_sum(fields: &[StructField]) -> (TokenStream, TokenStream) { - let fields: Vec<_> = fields - .iter() - .filter(|f| !f.skipped) - .map(|f| &f.member) - .collect(); - if !fields.is_empty() { - ( - quote! { - #( self.#fields.msg_size() as usize )+* - }, - quote! { - #( self.#fields.descriptor_count() as usize )+* - }, - ) - } else { - (quote!(0), quote!(0)) - } -} - -fn read_from_buffer_and_move_offset(name: &Ident, ty: &Type) -> TokenStream { - quote! { - let t = <#ty>::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let #name = t.0; - } -} - -fn write_to_buffer_and_move_offset(name: &Ident) -> TokenStream { - quote! { - let o = self.#name.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += self.#name.msg_size(); - __fd_offset += o; - } -} - -#[cfg(test)] -mod tests { - use crate::socket_msg_impl; - use quote::quote; - use syn::{parse_quote, DeriveInput}; - - #[test] - fn end_to_end_struct_test() { - let input: DeriveInput = parse_quote! { - struct MyMsg { - a: u8, - b: RawDescriptor, - c: u32, - } - }; - - let expected = quote! { - impl msg_socket::MsgOnSocket for MyMsg { - fn uses_descriptor() -> bool { - ::uses_descriptor() - || ::uses_descriptor() - || ::uses_descriptor() - } - fn msg_size(&self) -> usize { - self.a.msg_size() as usize - + self.b.msg_size() as usize - + self.c.msg_size() as usize - } - fn descriptor_count(&self) -> usize { - self.a.descriptor_count() as usize - + self.b.descriptor_count() as usize - + self.c.descriptor_count() as usize - } - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let a = t.0; - let t = ::read_from_buffer( - &buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let b = t.0; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let c = t.0; - Ok((Self { a, b, c }, __fd_offset)) - } - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - let o = self - .a - .write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += self.a.msg_size(); - __fd_offset += o; - let o = self - .b - .write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += self.b.msg_size(); - __fd_offset += o; - let o = self - .c - .write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += self.c.msg_size(); - __fd_offset += o; - Ok(__fd_offset) - } - } - - }; - - assert_eq!(socket_msg_impl(input).to_string(), expected.to_string()); - } - - #[test] - fn end_to_end_tuple_struct_test() { - let input: DeriveInput = parse_quote! { - struct MyMsg(u8, u32, File); - }; - - let expected = quote! { - impl msg_socket::MsgOnSocket for MyMsg { - fn uses_descriptor() -> bool { - ::uses_descriptor() || ::uses_descriptor() || ::uses_descriptor() - } - fn msg_size(&self) -> usize { - self.0.msg_size() as usize - + self.1.msg_size() as usize + self.2.msg_size() as usize - } - fn descriptor_count(&self) -> usize { - self.0.descriptor_count() as usize - + self.1.descriptor_count() as usize - + self.2.descriptor_count() as usize - } - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let tuple_tmp0 = t.0; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let tuple_tmp1 = t.0; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let tuple_tmp2 = t.0; - Ok((MyMsg(tuple_tmp0, tuple_tmp1, tuple_tmp2), __fd_offset)) - } - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - let MyMsg(tuple_tmp0, tuple_tmp1, tuple_tmp2) = self; - let o = tuple_tmp0.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += tuple_tmp0.msg_size(); - __fd_offset += o; - let o = tuple_tmp1.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += tuple_tmp1.msg_size(); - __fd_offset += o; - let o = tuple_tmp2.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += tuple_tmp2.msg_size(); - __fd_offset += o; - Ok(__fd_offset) - } - } - }; - - assert_eq!(socket_msg_impl(input).to_string(), expected.to_string()); - } - - #[test] - fn end_to_end_enum_test() { - let input: DeriveInput = parse_quote! { - enum MyMsg { - A(u8), - B, - C { - f0: u8, - f1: RawDescriptor, - }, - } - }; - - let expected = quote! { - impl msg_socket::MsgOnSocket for MyMsg { - fn uses_descriptor() -> bool { - ::uses_descriptor() - || ::uses_descriptor() - || ::uses_descriptor() - } - fn msg_size(&self) -> usize { - 1 + match self { - MyMsg::A(enum_field0) => enum_field0.msg_size(), - MyMsg::B => 0, - MyMsg::C { f0, f1 } => f0.msg_size() + f1.msg_size(), - } - } - fn descriptor_count(&self) -> usize { - match self { - MyMsg::A(enum_field0) => enum_field0.descriptor_count(), - MyMsg::B => 0, - MyMsg::C { f0, f1 } => f0.descriptor_count() + f1.descriptor_count(), - } - } - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let v = buffer - .get(0) - .ok_or(msg_socket::MsgError::WrongMsgBufferSize)?; - match v { - 0u8 => { - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let enum_field0 = t.0; - Ok((MyMsg::A(enum_field0), __fd_offset)) - } - 1u8 => Ok((MyMsg::B, 0)), - 2u8 => { - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let f0 = t.0; - let t = ::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?; - __offset += t.0.msg_size(); - __fd_offset += t.1; - let f1 = t.0; - Ok((MyMsg::C { f0, f1 }, __fd_offset)) - } - _ => Err(msg_socket::MsgError::InvalidType), - } - } - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - if buffer.is_empty() { - return Err(msg_socket::MsgError::WrongMsgBufferSize) - } - match self { - MyMsg::A(enum_field0) => { - buffer[0] = 0u8; - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - let o = enum_field0 - .write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += enum_field0.msg_size(); - __fd_offset += o; - Ok(__fd_offset) - } - MyMsg::B => { - buffer[0] = 1u8; - Ok(0) - } - MyMsg::C { f0, f1 } => { - buffer[0] = 2u8; - let mut __offset = 1usize; - let mut __fd_offset = 0usize; - let o = f0.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += f0.msg_size(); - __fd_offset += o; - let o = f1.write_to_buffer(&mut buffer[__offset..], &mut fds[__fd_offset..])?; - __offset += f1.msg_size(); - __fd_offset += o; - Ok(__fd_offset) - } - } - } - } - }; - - assert_eq!(socket_msg_impl(input).to_string(), expected.to_string()); - } - - #[test] - fn end_to_end_struct_skip_test() { - let input: DeriveInput = parse_quote! { - struct MyMsg { - #[msg_on_socket(skip)] - a: u8, - } - }; - - let expected = quote! { - impl msg_socket::MsgOnSocket for MyMsg { - fn msg_size(&self) -> usize { - 0 - } - fn descriptor_count(&self) -> usize { - 0 - } - unsafe fn read_from_buffer( - buffer: &[u8], - fds: &[RawDescriptor], - ) -> msg_socket::MsgResult<(Self, usize)> { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - Ok((Self { a: ::default() }, __fd_offset)) - } - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> msg_socket::MsgResult { - let mut __offset = 0usize; - let mut __fd_offset = 0usize; - Ok(__fd_offset) - } - } - - }; - - assert_eq!(socket_msg_impl(input).to_string(), expected.to_string()); - } -} diff --git a/msg_socket/src/lib.rs b/msg_socket/src/lib.rs deleted file mode 100644 index d6f90773b7..0000000000 --- a/msg_socket/src/lib.rs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -mod msg_on_socket; -mod serializable_descriptors; - -use std::io::{IoSlice, Result}; -use std::marker::PhantomData; - -use base::{ - handle_eintr, net::UnixSeqpacket, AsRawDescriptor, Error as SysError, RawDescriptor, ScmSocket, - UnsyncMarker, -}; -use cros_async::{Executor, IoSourceExt}; - -pub use crate::msg_on_socket::*; -pub use msg_on_socket_derive::*; - -/// Create a pair of socket. Request is send in one direction while response is in the other -/// direction. -pub fn pair( -) -> Result<(MsgSocket, MsgSocket)> { - let (sock1, sock2) = UnixSeqpacket::pair()?; - let requester = MsgSocket::new(sock1); - let responder = MsgSocket::new(sock2); - Ok((requester, responder)) -} - -/// Bidirection sock that support both send and recv. -pub struct MsgSocket { - sock: UnixSeqpacket, - _i: PhantomData, - _o: PhantomData, - _unsync_marker: UnsyncMarker, -} - -impl MsgSocket { - // Create a new MsgSocket. - pub fn new(s: UnixSeqpacket) -> MsgSocket { - MsgSocket { - sock: s, - _i: PhantomData, - _o: PhantomData, - _unsync_marker: PhantomData, - } - } - - // Creates an async receiver that implements `futures::Stream`. - pub fn async_receiver(&self, ex: &Executor) -> MsgResult> { - AsyncReceiver::new(self, ex) - } -} - -/// One direction socket that only supports sending. -pub struct Sender { - sock: UnixSeqpacket, - _m: PhantomData, -} - -impl Sender { - /// Create a new sender sock. - pub fn new(s: UnixSeqpacket) -> Sender { - Sender { - sock: s, - _m: PhantomData, - } - } -} - -/// One direction socket that only supports receiving. -pub struct Receiver { - sock: UnixSeqpacket, - _m: PhantomData, -} - -impl Receiver { - /// Create a new receiver sock. - pub fn new(s: UnixSeqpacket) -> Receiver { - Receiver { - sock: s, - _m: PhantomData, - } - } -} - -impl AsRef for MsgSocket { - fn as_ref(&self) -> &UnixSeqpacket { - &self.sock - } -} - -impl AsRawDescriptor for MsgSocket { - fn as_raw_descriptor(&self) -> RawDescriptor { - self.sock.as_raw_descriptor() - } -} - -impl AsRawDescriptor for &MsgSocket { - fn as_raw_descriptor(&self) -> RawDescriptor { - self.sock.as_raw_descriptor() - } -} - -impl AsRef for Sender { - fn as_ref(&self) -> &UnixSeqpacket { - &self.sock - } -} - -impl AsRawDescriptor for Sender { - fn as_raw_descriptor(&self) -> RawDescriptor { - self.sock.as_raw_descriptor() - } -} - -impl AsRef for Receiver { - fn as_ref(&self) -> &UnixSeqpacket { - &self.sock - } -} - -impl AsRawDescriptor for Receiver { - fn as_raw_descriptor(&self) -> RawDescriptor { - self.sock.as_raw_descriptor() - } -} - -/// Types that could send a message. -pub trait MsgSender: AsRef { - type M: MsgOnSocket; - fn send(&self, msg: &Self::M) -> MsgResult<()> { - let msg_size = msg.msg_size(); - let descriptor_size = msg.descriptor_count(); - let mut msg_buffer: Vec = vec![0; msg_size]; - let mut descriptor_buffer: Vec = vec![0; descriptor_size]; - - let descriptor_size = msg.write_to_buffer(&mut msg_buffer, &mut descriptor_buffer)?; - let sock: &UnixSeqpacket = self.as_ref(); - if descriptor_size == 0 { - handle_eintr!(sock.send(&msg_buffer)) - .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?; - } else { - let ioslice = IoSlice::new(&msg_buffer[..]); - sock.send_with_fds(&[ioslice], &descriptor_buffer[0..descriptor_size]) - .map_err(MsgError::Send)?; - } - Ok(()) - } -} - -/// Types that could receive a message. -pub trait MsgReceiver: AsRef { - type M: MsgOnSocket; - fn recv(&self) -> MsgResult { - let sock: &UnixSeqpacket = self.as_ref(); - - let (msg_buffer, descriptor_buffer) = { - if Self::M::uses_descriptor() { - sock.recv_as_vec_with_fds() - .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))? - } else { - ( - sock.recv_as_vec().map_err(|e| { - MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))) - })?, - vec![], - ) - } - }; - - if msg_buffer.is_empty() && Self::M::fixed_size() != Some(0) { - return Err(MsgError::RecvZero); - } - - if let Some(fixed_size) = Self::M::fixed_size() { - if fixed_size != msg_buffer.len() { - return Err(MsgError::BadRecvSize { - expected: fixed_size, - actual: msg_buffer.len(), - }); - } - } - - // Safe because fd buffer is read from socket. - let (v, read_descriptor_size) = - unsafe { Self::M::read_from_buffer(&msg_buffer, &descriptor_buffer)? }; - if descriptor_buffer.len() != read_descriptor_size { - return Err(MsgError::NotExpectDescriptor); - } - Ok(v) - } -} - -impl MsgSender for MsgSocket { - type M = I; -} -impl MsgReceiver for MsgSocket { - type M = O; -} - -impl MsgSender for Sender { - type M = I; -} -impl MsgReceiver for Receiver { - type M = O; -} - -/// Asynchronous adaptor for `MsgSocket`. -pub struct AsyncReceiver<'m, I: MsgOnSocket, O: MsgOnSocket> { - // This weirdness is because we can't directly implement IntoAsync for &MsgSocket because there - // is no AsRawFd impl for references. - inner: &'m MsgSocket, - sock: Box + 'm>, -} - -impl<'m, I: MsgOnSocket, O: MsgOnSocket> AsyncReceiver<'m, I, O> { - fn new(msg_socket: &'m MsgSocket, ex: &Executor) -> MsgResult { - let sock = ex - .async_from(&msg_socket.sock) - .map_err(MsgError::CreateAsync)?; - Ok(AsyncReceiver { - inner: msg_socket, - sock, - }) - } - - pub async fn next(&mut self) -> MsgResult { - self.sock.wait_readable().await.unwrap(); - self.inner.recv() - } -} diff --git a/msg_socket/src/msg_on_socket.rs b/msg_socket/src/msg_on_socket.rs deleted file mode 100644 index 5db5217725..0000000000 --- a/msg_socket/src/msg_on_socket.rs +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -mod slice; -mod tuple; - -use std::fmt::{self, Display}; -use std::mem::{size_of, transmute_copy, MaybeUninit}; -use std::result; -use std::sync::Arc; - -use base::{Error as SysError, RawDescriptor}; -use data_model::*; -use slice::{slice_read_helper, slice_write_helper}; - -#[derive(Debug)] -/// An error during transaction or serialization/deserialization. -pub enum MsgError { - /// Error while creating an async socket. - CreateAsync(cros_async::AsyncError), - /// Error while sending a request or response. - Send(SysError), - /// Error while receiving a request or response. - Recv(SysError), - /// The type of a received request or response is unknown. - InvalidType, - /// There was not the expected amount of data when receiving a message. The inner - /// value is how much data is expected and how much data was actually received. - BadRecvSize { expected: usize, actual: usize }, - /// There was no data received when the socket `recv`-ed. - RecvZero, - /// There was no associated file descriptor received for a request that expected it. - ExpectDescriptor, - /// There was some associated file descriptor received but not used when deserialize. - NotExpectDescriptor, - /// Failed to set flags on the file descriptor. - SettingDescriptorFlags(SysError), - /// Trying to serialize/deserialize, but fd buffer size is too small. This typically happens - /// when max_fd_count() returns a value that is too small. - WrongDescriptorBufferSize, - /// Trying to serialize/deserialize, but msg buffer size is too small. This typically happens - /// when msg_size() returns a value that is too small. - WrongMsgBufferSize, -} - -pub type MsgResult = result::Result; - -impl Display for MsgError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::MsgError::*; - - match self { - CreateAsync(e) => write!(f, "failed to create an async socket: {}", e), - Send(e) => write!(f, "failed to send request or response: {}", e), - Recv(e) => write!(f, "failed to receive request or response: {}", e), - InvalidType => write!(f, "invalid type"), - BadRecvSize { expected, actual } => write!( - f, - "wrong amount of data received; expected {} bytes; got {} bytes", - expected, actual - ), - RecvZero => write!(f, "received zero data"), - ExpectDescriptor => write!(f, "missing associated file descriptor for request"), - NotExpectDescriptor => write!(f, "unexpected file descriptor is unused"), - SettingDescriptorFlags(e) => { - write!(f, "failed setting flags on the message descriptor: {}", e) - } - WrongDescriptorBufferSize => write!(f, "descriptor buffer size too small"), - WrongMsgBufferSize => write!(f, "msg buffer size too small"), - } - } -} - -/// A msg that could be serialized to and deserialize from array in little endian. -/// -/// For structs, we always have fixed size of bytes and fixed count of fds. -/// For enums, the size needed might be different for each variant. -/// -/// e.g. -/// ``` -/// use base::RawDescriptor; -/// enum Message { -/// VariantA(u8), -/// VariantB(u32, RawDescriptor), -/// VariantC, -/// } -/// ``` -/// -/// For variant A, we need 1 byte to store its inner value. -/// For variant B, we need 4 bytes and 1 RawDescriptor to store its inner value. -/// For variant C, we need 0 bytes to store its inner value. -/// When we serialize Message to (buffer, fd_buffer), we always use fixed number of bytes in -/// the buffer. Unused buffer bytes will be padded with zero. -/// However, for fd_buffer, we could not do the same thing. Otherwise, we are essentially sending -/// fd 0 through the socket. -/// Thus, read/write functions always the return correct count of fds in this variant. There will be -/// no padding in fd_buffer. -pub trait MsgOnSocket: Sized { - // `true` if this structure can potentially serialize descriptors. - fn uses_descriptor() -> bool { - false - } - - // Returns `Some(size)` if this structure always has a fixed size. - fn fixed_size() -> Option { - None - } - - /// Size of message in bytes. - fn msg_size(&self) -> usize { - Self::fixed_size().unwrap() - } - - /// Number of FDs in this message. This must be overridden if `uses_descriptor()` returns true. - fn descriptor_count(&self) -> usize { - assert!(!Self::uses_descriptor()); - 0 - } - /// Returns (self, fd read count). - /// This function is safe only when: - /// 0. fds contains valid fds, received from socket, serialized by Self::write_to_buffer. - /// 1. For enum, fds contains correct fd layout of the particular variant. - /// 2. write_to_buffer is implemented correctly(put valid fds into the buffer, has no padding, - /// return correct count). - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)>; - - /// Serialize self to buffers. - fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawDescriptor]) -> MsgResult; -} - -impl MsgOnSocket for SysError { - fn fixed_size() -> Option { - Some(size_of::()) - } - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - let (v, size) = u32::read_from_buffer(buffer, fds)?; - Ok((SysError::new(v as i32), size)) - } - fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawDescriptor]) -> MsgResult { - let v = self.errno() as u32; - v.write_to_buffer(buffer, fds) - } -} - -impl MsgOnSocket for Option { - fn uses_descriptor() -> bool { - T::uses_descriptor() - } - - fn msg_size(&self) -> usize { - match self { - Some(v) => v.msg_size() + 1, - None => 1, - } - } - - fn descriptor_count(&self) -> usize { - match self { - Some(v) => v.descriptor_count(), - None => 0, - } - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - match buffer[0] { - 0 => Ok((None, 0)), - 1 => { - let (inner, len) = T::read_from_buffer(&buffer[1..], fds)?; - Ok((Some(inner), len)) - } - _ => Err(MsgError::InvalidType), - } - } - - fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawDescriptor]) -> MsgResult { - match self { - None => { - buffer[0] = 0; - Ok(0) - } - Some(inner) => { - buffer[0] = 1; - inner.write_to_buffer(&mut buffer[1..], fds) - } - } - } -} - -impl MsgOnSocket for Arc { - fn uses_descriptor() -> bool { - T::uses_descriptor() - } - - fn msg_size(&self) -> usize { - (**self).msg_size() - } - - fn descriptor_count(&self) -> usize { - (**self).descriptor_count() - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - T::read_from_buffer(buffer, fds).map(|(v, count)| (Arc::new(v), count)) - } - - fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawDescriptor]) -> MsgResult { - (**self).write_to_buffer(buffer, fds) - } -} - -impl MsgOnSocket for () { - fn fixed_size() -> Option { - Some(0) - } - - unsafe fn read_from_buffer(_buffer: &[u8], _fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - Ok(((), 0)) - } - - fn write_to_buffer(&self, _buffer: &mut [u8], _fds: &mut [RawDescriptor]) -> MsgResult { - Ok(0) - } -} - -// usize could be different sizes on different targets. We always use u64. -impl MsgOnSocket for usize { - fn msg_size(&self) -> usize { - size_of::() - } - unsafe fn read_from_buffer(buffer: &[u8], _fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - if buffer.len() < size_of::() { - return Err(MsgError::WrongMsgBufferSize); - } - let t = u64::from_le_bytes(slice_to_array(buffer)); - Ok((t as usize, 0)) - } - - fn write_to_buffer(&self, buffer: &mut [u8], _fds: &mut [RawDescriptor]) -> MsgResult { - if buffer.len() < size_of::() { - return Err(MsgError::WrongMsgBufferSize); - } - let t: Le64 = (*self as u64).into(); - buffer[0..self.msg_size()].copy_from_slice(t.as_slice()); - Ok(0) - } -} - -// Encode bool as a u8 of value 0 or 1 -impl MsgOnSocket for bool { - fn msg_size(&self) -> usize { - size_of::() - } - unsafe fn read_from_buffer(buffer: &[u8], _fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - if buffer.len() < size_of::() { - return Err(MsgError::WrongMsgBufferSize); - } - let t: u8 = buffer[0]; - match t { - 0 => Ok((false, 0)), - 1 => Ok((true, 0)), - _ => Err(MsgError::InvalidType), - } - } - fn write_to_buffer(&self, buffer: &mut [u8], _fds: &mut [RawDescriptor]) -> MsgResult { - if buffer.len() < size_of::() { - return Err(MsgError::WrongMsgBufferSize); - } - buffer[0] = *self as u8; - Ok(0) - } -} - -macro_rules! le_impl { - ($type:ident, $native_type:ident) => { - impl MsgOnSocket for $type { - fn fixed_size() -> Option { - Some(size_of::<$native_type>()) - } - - unsafe fn read_from_buffer( - buffer: &[u8], - _fds: &[RawDescriptor], - ) -> MsgResult<(Self, usize)> { - if buffer.len() < size_of::<$native_type>() { - return Err(MsgError::WrongMsgBufferSize); - } - let t = $native_type::from_le_bytes(slice_to_array(buffer)); - Ok((t.into(), 0)) - } - - fn write_to_buffer( - &self, - buffer: &mut [u8], - _fds: &mut [RawDescriptor], - ) -> MsgResult { - if buffer.len() < size_of::<$native_type>() { - return Err(MsgError::WrongMsgBufferSize); - } - let t: $native_type = self.clone().into(); - buffer[0..self.msg_size()].copy_from_slice(&t.to_le_bytes()); - Ok(0) - } - } - }; -} - -le_impl!(u8, u8); -le_impl!(u16, u16); -le_impl!(u32, u32); -le_impl!(u64, u64); - -le_impl!(Le16, u16); -le_impl!(Le32, u32); -le_impl!(Le64, u64); - -fn simple_read(buffer: &[u8], offset: &mut usize) -> MsgResult { - assert!(!T::uses_descriptor()); - // Safety for T::read_from_buffer depends on the given FDs being valid, but we pass no FDs. - let (v, _) = unsafe { T::read_from_buffer(&buffer[*offset..], &[])? }; - *offset += v.msg_size(); - Ok(v) -} - -fn simple_write(v: T, buffer: &mut [u8], offset: &mut usize) -> MsgResult<()> { - assert!(!T::uses_descriptor()); - v.write_to_buffer(&mut buffer[*offset..], &mut [])?; - *offset += v.msg_size(); - Ok(()) -} - -// Converts a slice into an array of fixed size inferred from by the return value. Panics if the -// slice is too small, but will tolerate slices that are too large. -fn slice_to_array(s: &[T]) -> O -where - T: Copy, - O: Default + AsMut<[T]>, -{ - let mut o = O::default(); - let o_slice = o.as_mut(); - let len = o_slice.len(); - o_slice.copy_from_slice(&s[..len]); - o -} - -macro_rules! array_impls { - ($N:expr, $t: ident $($ts:ident)*) - => { - impl MsgOnSocket for [T; $N] { - fn uses_descriptor() -> bool { - T::uses_descriptor() - } - - fn fixed_size() -> Option { - Some(T::fixed_size()? * $N) - } - - fn msg_size(&self) -> usize { - match T::fixed_size() { - Some(s) => s * $N, - None => self.iter().map(|i| i.msg_size()).sum::() + size_of::() * $N - } - } - - fn descriptor_count(&self) -> usize { - if T::uses_descriptor() { - self.iter().map(|i| i.descriptor_count()).sum() - } else { - 0 - } - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) - -> MsgResult<(Self, usize)> { - // Taken from the canonical example of initializing an array, the `assume_init` can - // be assumed safe because the array elements (`MaybeUninit` in this case) - // themselves don't require initializing. - let mut msgs: [MaybeUninit; $N] = MaybeUninit::uninit().assume_init(); - - let fd_count = slice_read_helper(buffer, fds, &mut msgs)?; - - // Also taken from the canonical example, we initialized every member of the array - // in the first loop of this function, so it is safe to `transmute_copy` the array - // of `MaybeUninit` data to plain data. Although `transmute`, which checks the - // types' sizes, would have been preferred in this code, the compiler complains with - // "cannot transmute between types of different sizes, or dependently-sized types." - // Because this function operates on generic data, the type is "dependently-sized" - // and so the compiler will not check that the size of the input and output match. - // See this issue for details: https://github.com/rust-lang/rust/issues/61956 - Ok((transmute_copy::<_, [T; $N]>(&msgs), fd_count)) - } - - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> MsgResult { - slice_write_helper(self, buffer, fds) - } - } - #[cfg(test)] - mod $t { - use super::MsgOnSocket; - - #[test] - fn read_write_option_array() { - type ArrayType = [Option; $N]; - let array = [Some($N); $N]; - let mut buffer = vec![0; array.msg_size()]; - array.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_array = unsafe { ArrayType::read_from_buffer(&buffer, &[]) }.unwrap().0; - - assert!(array.iter().eq(read_array.iter())); - } - - #[test] - fn read_write_fixed() { - type ArrayType = [u32; $N]; - let mut buffer = vec![0; ::fixed_size().unwrap()]; - let array = [$N as u32; $N]; - array.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_array = unsafe { ArrayType::read_from_buffer(&buffer, &[]) }.unwrap().0; - - assert!(array.iter().eq(read_array.iter())); - } - } - array_impls!(($N - 1), $($ts)*); - }; - {$N:expr, } => {}; -} - -array_impls! { - 64, tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 tmp7 tmp8 tmp9 tmp10 tmp11 tmp12 tmp13 tmp14 tmp15 tmp16 - tmp17 tmp18 tmp19 tmp20 tmp21 tmp22 tmp23 tmp24 tmp25 tmp26 tmp27 tmp28 tmp29 tmp30 tmp31 - tmp32 tmp33 tmp34 tmp35 tmp36 tmp37 tmp38 tmp39 tmp40 tmp41 tmp42 tmp43 tmp44 tmp45 tmp46 - tmp47 tmp48 tmp49 tmp50 tmp51 tmp52 tmp53 tmp54 tmp55 tmp56 tmp57 tmp58 tmp59 tmp60 tmp61 - tmp62 tmp63 tmp64 -} diff --git a/msg_socket/src/msg_on_socket/slice.rs b/msg_socket/src/msg_on_socket/slice.rs deleted file mode 100644 index 05df5e142f..0000000000 --- a/msg_socket/src/msg_on_socket/slice.rs +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2020 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use base::RawDescriptor; -use std::mem::{size_of, ManuallyDrop, MaybeUninit}; -use std::ptr::drop_in_place; - -use crate::{MsgOnSocket, MsgResult}; - -use super::{simple_read, simple_write}; - -/// Helper used by the types that read a slice of homegenously typed data. -/// -/// # Safety -/// This function has the same safety requirements as `T::read_from_buffer`, with the additional -/// requirements that the `msgs` are only used on success of this function -pub unsafe fn slice_read_helper( - buffer: &[u8], - fds: &[RawDescriptor], - msgs: &mut [MaybeUninit], -) -> MsgResult { - let mut offset = 0usize; - let mut fd_offset = 0usize; - - // In case of an error, we need to keep track of how many elements got initialized. - // In order to perform the necessary drops, the below loop is executed in a closure - // to capture errors without returning. - let mut last_index = 0; - let res = (|| { - for msg in &mut msgs[..] { - let element_size = match T::fixed_size() { - Some(s) => s, - None => simple_read::(buffer, &mut offset)? as usize, - }; - // Assuming the unsafe caller gave valid FDs, this call should be safe. - let (m, fd_size) = T::read_from_buffer(&buffer[offset..], &fds[fd_offset..])?; - *msg = MaybeUninit::new(m); - offset += element_size; - fd_offset += fd_size; - last_index += 1; - } - Ok(()) - })(); - - // Because `MaybeUninit` will not automatically call drops, we have to drop the - // partially initialized array manually in the case of an error. - if let Err(e) = res { - for msg in &mut msgs[..last_index] { - // The call to `as_mut_ptr()` turns the `MaybeUninit` element of the array - // into a pointer, which can be used with `drop_in_place` to call the - // destructor without moving the element, which is impossible. This is safe - // because `last_index` prevents this loop from traversing into the - // uninitialized parts of the array. - drop_in_place(msg.as_mut_ptr()); - } - return Err(e); - } - - Ok(fd_offset) -} - -/// Helper used by the types that write a slice of homegenously typed data. -pub fn slice_write_helper( - msgs: &[T], - buffer: &mut [u8], - fds: &mut [RawDescriptor], -) -> MsgResult { - let mut offset = 0usize; - let mut fd_offset = 0usize; - for msg in msgs { - let element_size = match T::fixed_size() { - Some(s) => s, - None => { - let element_size = msg.msg_size(); - simple_write(element_size as u64, buffer, &mut offset)?; - element_size as usize - } - }; - let fd_size = msg.write_to_buffer(&mut buffer[offset..], &mut fds[fd_offset..])?; - offset += element_size; - fd_offset += fd_size; - } - - Ok(fd_offset) -} - -impl MsgOnSocket for Vec { - fn uses_descriptor() -> bool { - T::uses_descriptor() - } - - fn fixed_size() -> Option { - None - } - - fn msg_size(&self) -> usize { - let vec_size = match T::fixed_size() { - Some(s) => s * self.len(), - None => self.iter().map(|i| i.msg_size() + size_of::()).sum(), - }; - size_of::() + vec_size - } - - fn descriptor_count(&self) -> usize { - if T::uses_descriptor() { - self.iter().map(|i| i.descriptor_count()).sum() - } else { - 0 - } - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - let mut offset = 0; - let len = simple_read::(buffer, &mut offset)? as usize; - let mut msgs: Vec> = Vec::with_capacity(len); - msgs.set_len(len); - let fd_count = slice_read_helper(&buffer[offset..], fds, &mut msgs)?; - let mut msgs = ManuallyDrop::new(msgs); - Ok(( - Vec::from_raw_parts(msgs.as_mut_ptr() as *mut T, msgs.len(), msgs.capacity()), - fd_count, - )) - } - - fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawDescriptor]) -> MsgResult { - let mut offset = 0; - simple_write(self.len() as u64, buffer, &mut offset)?; - slice_write_helper(self, &mut buffer[offset..], fds) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn read_write_1_fixed() { - let vec = vec![1u32]; - let mut buffer = vec![0; vec.msg_size()]; - vec.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_vec = unsafe { >::read_from_buffer(&buffer, &[]) } - .unwrap() - .0; - - assert_eq!(vec, read_vec); - } - - #[test] - fn read_write_8_fixed() { - let vec = vec![1u16, 1, 3, 5, 8, 13, 21, 34]; - let mut buffer = vec![0; vec.msg_size()]; - vec.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_vec = unsafe { >::read_from_buffer(&buffer, &[]) } - .unwrap() - .0; - assert_eq!(vec, read_vec); - } - - #[test] - fn read_write_1() { - let vec = vec![Some(1u64)]; - let mut buffer = vec![0; vec.msg_size()]; - println!("{:?}", vec.msg_size()); - vec.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_vec = unsafe { >::read_from_buffer(&buffer, &[]) } - .unwrap() - .0; - - assert_eq!(vec, read_vec); - } - - #[test] - fn read_write_4() { - let vec = vec![Some(12u16), Some(0), None, None]; - let mut buffer = vec![0; vec.msg_size()]; - vec.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_vec = unsafe { >::read_from_buffer(&buffer, &[]) } - .unwrap() - .0; - - assert_eq!(vec, read_vec); - } -} diff --git a/msg_socket/src/msg_on_socket/tuple.rs b/msg_socket/src/msg_on_socket/tuple.rs deleted file mode 100644 index 90784bfef0..0000000000 --- a/msg_socket/src/msg_on_socket/tuple.rs +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2020 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use base::RawDescriptor; -use std::mem::size_of; - -use crate::{MsgOnSocket, MsgResult}; - -use super::{simple_read, simple_write}; - -// Returns the size of one part of a tuple. -fn tuple_size_helper(v: &T) -> usize { - T::fixed_size().unwrap_or_else(|| v.msg_size() + size_of::()) -} - -unsafe fn tuple_read_helper( - buffer: &[u8], - fds: &[RawDescriptor], - buffer_index: &mut usize, - fd_index: &mut usize, -) -> MsgResult { - let end = match T::fixed_size() { - Some(_) => buffer.len(), - None => { - let len = simple_read::(buffer, buffer_index)? as usize; - *buffer_index + len - } - }; - let (v, fd_read) = T::read_from_buffer(&buffer[*buffer_index..end], &fds[*fd_index..])?; - *buffer_index += v.msg_size(); - *fd_index += fd_read; - Ok(v) -} - -fn tuple_write_helper( - v: &T, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - buffer_index: &mut usize, - fd_index: &mut usize, -) -> MsgResult<()> { - let end = match T::fixed_size() { - Some(_) => buffer.len(), - None => { - let len = v.msg_size(); - simple_write(len as u64, buffer, buffer_index)?; - *buffer_index + len - } - }; - let fd_written = v.write_to_buffer(&mut buffer[*buffer_index..end], &mut fds[*fd_index..])?; - *buffer_index += v.msg_size(); - *fd_index += fd_written; - Ok(()) -} - -macro_rules! tuple_impls { - () => {}; - ($t: ident) => { - #[allow(unused_variables, non_snake_case)] - impl<$t: MsgOnSocket> MsgOnSocket for ($t,) { - fn uses_descriptor() -> bool { - $t::uses_descriptor() - } - - fn descriptor_count(&self) -> usize { - self.0.descriptor_count() - } - - fn fixed_size() -> Option { - $t::fixed_size() - } - - fn msg_size(&self) -> usize { - self.0.msg_size() - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - let (t, s) = $t::read_from_buffer(buffer, fds)?; - Ok(((t,), s)) - } - - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> MsgResult { - self.0.write_to_buffer(buffer, fds) - } - } - }; - ($t: ident, $($ts:ident),*) => { - #[allow(unused_variables, non_snake_case)] - impl<$t: MsgOnSocket $(, $ts: MsgOnSocket)*> MsgOnSocket for ($t$(, $ts)*) { - fn uses_descriptor() -> bool { - $t::uses_descriptor() $(|| $ts::uses_descriptor())* - } - - fn descriptor_count(&self) -> usize { - if Self::uses_descriptor() { - return 0; - } - let ($t $(,$ts)*) = self; - $t.descriptor_count() $(+ $ts.descriptor_count())* - } - - fn fixed_size() -> Option { - // Returns None if any element is not fixed size. - Some($t::fixed_size()? $(+ $ts::fixed_size()?)*) - } - - fn msg_size(&self) -> usize { - if let Some(size) = Self::fixed_size() { - return size - } - - let ($t $(,$ts)*) = self; - tuple_size_helper($t) $(+ tuple_size_helper($ts))* - } - - unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawDescriptor]) -> MsgResult<(Self, usize)> { - let mut buffer_index = 0; - let mut fd_index = 0; - Ok(( - ( - tuple_read_helper(buffer, fds, &mut buffer_index, &mut fd_index)?, - $({ - // Dummy let used to trigger the correct number of iterations. - let $ts = (); - tuple_read_helper(buffer, fds, &mut buffer_index, &mut fd_index)? - },)* - ), - fd_index - )) - } - - fn write_to_buffer( - &self, - buffer: &mut [u8], - fds: &mut [RawDescriptor], - ) -> MsgResult { - let mut buffer_index = 0; - let mut fd_index = 0; - let ($t $(,$ts)*) = self; - tuple_write_helper($t, buffer, fds, &mut buffer_index, &mut fd_index)?; - $( - tuple_write_helper($ts, buffer, fds, &mut buffer_index, &mut fd_index)?; - )* - Ok(fd_index) - } - } - tuple_impls!{ $($ts),* } - } -} - -// Imlpement tuple for up to 8 elements. -tuple_impls! { A, B, C, D, E, F, G, H } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn read_write_1_fixed() { - let tuple = (1,); - let mut buffer = vec![0; tuple.msg_size()]; - tuple.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_tuple = unsafe { <(u32,)>::read_from_buffer(&buffer, &[]) } - .unwrap() - .0; - - assert_eq!(tuple, read_tuple); - } - - #[test] - fn read_write_8_fixed() { - let tuple = (1u32, 2u8, 3u16, 4u64, 5u32, 6u16, 7u8, 8u8); - let mut buffer = vec![0; tuple.msg_size()]; - tuple.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_tuple = unsafe { <_>::read_from_buffer(&buffer, &[]) }.unwrap().0; - - assert_eq!(tuple, read_tuple); - } - - #[test] - fn read_write_1() { - let tuple = (Some(1u64),); - let mut buffer = vec![0; tuple.msg_size()]; - tuple.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_tuple = unsafe { <_>::read_from_buffer(&buffer, &[]) }.unwrap().0; - - assert_eq!(tuple, read_tuple); - } - - #[test] - fn read_write_4() { - let tuple = (Some(12u16), Some(false), None::, None::); - let mut buffer = vec![0; tuple.msg_size()]; - println!("{:?}", tuple.msg_size()); - tuple.write_to_buffer(&mut buffer, &mut []).unwrap(); - let read_tuple = unsafe { <_>::read_from_buffer(&buffer, &[]) }.unwrap().0; - - assert_eq!(tuple, read_tuple); - } -} diff --git a/msg_socket/src/serializable_descriptors.rs b/msg_socket/src/serializable_descriptors.rs deleted file mode 100644 index 21ce84b7e1..0000000000 --- a/msg_socket/src/serializable_descriptors.rs +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use crate::msg_on_socket::{MsgError, MsgOnSocket, MsgResult}; -use base::{AsRawDescriptor, Event, FromRawDescriptor, RawDescriptor}; -use std::fs::File; -use std::net::{TcpListener, TcpStream, UdpSocket}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; -use std::os::unix::net::{UnixDatagram, UnixListener, UnixStream}; - -macro_rules! rawdescriptor_impl { - ($type:ident) => { - impl MsgOnSocket for $type { - fn uses_descriptor() -> bool { - true - } - fn msg_size(&self) -> usize { - 0 - } - fn descriptor_count(&self) -> usize { - 1 - } - unsafe fn read_from_buffer( - _buffer: &[u8], - descriptors: &[RawDescriptor], - ) -> MsgResult<(Self, usize)> { - if descriptors.len() < 1 { - return Err(MsgError::ExpectDescriptor); - } - Ok(($type::from_raw_descriptor(descriptors[0]), 1)) - } - fn write_to_buffer( - &self, - _buffer: &mut [u8], - descriptors: &mut [RawDescriptor], - ) -> MsgResult { - if descriptors.is_empty() { - return Err(MsgError::WrongDescriptorBufferSize); - } - descriptors[0] = self.as_raw_descriptor(); - Ok(1) - } - } - }; -} - -rawdescriptor_impl!(Event); -rawdescriptor_impl!(File); - -macro_rules! rawfd_impl { - ($type:ident) => { - impl MsgOnSocket for $type { - fn uses_descriptor() -> bool { - true - } - fn msg_size(&self) -> usize { - 0 - } - fn descriptor_count(&self) -> usize { - 1 - } - unsafe fn read_from_buffer(_buffer: &[u8], fds: &[RawFd]) -> MsgResult<(Self, usize)> { - if fds.len() < 1 { - return Err(MsgError::ExpectDescriptor); - } - Ok(($type::from_raw_fd(fds[0]), 1)) - } - fn write_to_buffer(&self, _buffer: &mut [u8], fds: &mut [RawFd]) -> MsgResult { - if fds.is_empty() { - return Err(MsgError::WrongDescriptorBufferSize); - } - fds[0] = self.as_raw_fd(); - Ok(1) - } - } - }; -} - -rawfd_impl!(UnixStream); -rawfd_impl!(TcpStream); -rawfd_impl!(TcpListener); -rawfd_impl!(UdpSocket); -rawfd_impl!(UnixListener); -rawfd_impl!(UnixDatagram); diff --git a/msg_socket/tests/enum.rs b/msg_socket/tests/enum.rs deleted file mode 100644 index 7f5998bdcd..0000000000 --- a/msg_socket/tests/enum.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use base::{Event, RawDescriptor}; - -use msg_socket::*; - -#[derive(MsgOnSocket)] -struct DummyRequest {} - -#[derive(MsgOnSocket)] -enum Response { - A(u8), - B, - C(u32, Event), - D([u8; 4]), - E { f0: u8, f1: u32 }, -} - -#[test] -fn sock_send_recv_enum() { - let (req, res) = pair::().unwrap(); - let e0 = Event::new().unwrap(); - let e1 = e0.try_clone().unwrap(); - res.send(&Response::C(0xf0f0, e0)).unwrap(); - let r = req.recv().unwrap(); - match r { - Response::C(v, efd) => { - assert_eq!(v, 0xf0f0); - efd.write(0x0f0f).unwrap(); - } - _ => panic!("wrong type"), - }; - assert_eq!(e1.read().unwrap(), 0x0f0f); - - res.send(&Response::B).unwrap(); - match req.recv().unwrap() { - Response::B => {} - _ => panic!("Wrong enum type"), - }; - - res.send(&Response::A(0x3)).unwrap(); - match req.recv().unwrap() { - Response::A(v) => assert_eq!(v, 0x3), - _ => panic!("Wrong enum type"), - }; - - res.send(&Response::D([0, 1, 2, 3])).unwrap(); - match req.recv().unwrap() { - Response::D(v) => assert_eq!(v, [0, 1, 2, 3]), - _ => panic!("Wrong enum type"), - }; - - res.send(&Response::E { - f0: 0x12, - f1: 0x0f0f, - }) - .unwrap(); - match req.recv().unwrap() { - Response::E { f0, f1 } => { - assert_eq!(f0, 0x12); - assert_eq!(f1, 0x0f0f); - } - _ => panic!("Wrong enum type"), - }; -} diff --git a/msg_socket/tests/struct.rs b/msg_socket/tests/struct.rs deleted file mode 100644 index 8e3c93f4a7..0000000000 --- a/msg_socket/tests/struct.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use base::{Event, RawDescriptor}; - -use msg_socket::*; - -#[derive(MsgOnSocket)] -struct Request { - field0: u8, - field1: Event, - field2: u32, - field3: bool, -} - -#[derive(MsgOnSocket)] -struct DummyResponse {} - -#[test] -fn sock_send_recv_struct() { - let (req, res) = pair::().unwrap(); - let e0 = Event::new().unwrap(); - let e1 = e0.try_clone().unwrap(); - req.send(&Request { - field0: 2, - field1: e0, - field2: 0xf0f0, - field3: true, - }) - .unwrap(); - let r = res.recv().unwrap(); - assert_eq!(r.field0, 2); - assert_eq!(r.field2, 0xf0f0); - assert_eq!(r.field3, true); - r.field1.write(0x0f0f).unwrap(); - assert_eq!(e1.read().unwrap(), 0x0f0f); -} diff --git a/msg_socket/tests/tuple.rs b/msg_socket/tests/tuple.rs deleted file mode 100644 index ae008135f1..0000000000 --- a/msg_socket/tests/tuple.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use base::{Event, RawDescriptor}; -use msg_socket::*; - -#[derive(MsgOnSocket)] -struct Message(u8, u16, Event); - -#[test] -fn sock_send_recv_tuple() { - let (req, res) = pair::().unwrap(); - let e0 = Event::new().unwrap(); - let e1 = e0.try_clone().unwrap(); - req.send(&Message(1, 0x12, e0)).unwrap(); - let r = res.recv().unwrap(); - assert_eq!(r.0, 1); - assert_eq!(r.1, 0x12); - r.2.write(0x0f0f).unwrap(); - assert_eq!(e1.read().unwrap(), 0x0f0f); -} diff --git a/msg_socket/tests/unit.rs b/msg_socket/tests/unit.rs deleted file mode 100644 index 9855752f83..0000000000 --- a/msg_socket/tests/unit.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use msg_socket::*; - -#[test] -fn sock_send_recv_unit() { - let (req, res) = pair::<(), ()>().unwrap(); - req.send(&()).unwrap(); - let _ = res.recv().unwrap(); -}