1 // Copyright 2021 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::{ 6 io::IoSlice, 7 marker::PhantomData, 8 os::unix::prelude::{AsRawFd, RawFd}, 9 time::Duration, 10 }; 11 12 use crate::descriptor::{AsRawDescriptor, FromRawDescriptor, SafeDescriptor}; 13 use crate::{ 14 platform::{deserialize_with_descriptors, SerializeDescriptors}, 15 tube::{Error, RecvTube, Result, SendTube}, 16 RawDescriptor, ReadNotifier, ScmSocket, UnixSeqpacket, UnsyncMarker, 17 }; 18 19 use serde::{de::DeserializeOwned, Deserialize, Serialize}; 20 21 /// Bidirectional tube that support both send and recv. 22 #[derive(Serialize, Deserialize)] 23 pub struct Tube { 24 socket: UnixSeqpacket, 25 26 // Windows is !Sync. We share that characteristic to prevent writing cross-platform incompatible 27 // code. 28 _unsync_marker: UnsyncMarker, 29 } 30 31 impl Tube { 32 /// Create a pair of connected tubes. Request is sent in one direction while response is in the 33 /// other direction. pair() -> Result<(Tube, Tube)>34 pub fn pair() -> Result<(Tube, Tube)> { 35 let (socket1, socket2) = UnixSeqpacket::pair().map_err(Error::Pair)?; 36 let tube1 = Tube::new(socket1); 37 let tube2 = Tube::new(socket2); 38 Ok((tube1, tube2)) 39 } 40 41 /// Create a new `Tube`. new(socket: UnixSeqpacket) -> Tube42 pub fn new(socket: UnixSeqpacket) -> Tube { 43 Tube { 44 socket, 45 _unsync_marker: PhantomData, 46 } 47 } 48 49 /// DO NOT USE this method directly as it will become private soon (b/221484449). Use a 50 /// directional Tube pair instead. 51 #[deprecated] try_clone(&self) -> Result<Self>52 pub fn try_clone(&self) -> Result<Self> { 53 self.socket.try_clone().map(Tube::new).map_err(Error::Clone) 54 } 55 send<T: Serialize>(&self, msg: &T) -> Result<()>56 pub fn send<T: Serialize>(&self, msg: &T) -> Result<()> { 57 let msg_serialize = SerializeDescriptors::new(&msg); 58 let msg_json = serde_json::to_vec(&msg_serialize).map_err(Error::Json)?; 59 let msg_descriptors = msg_serialize.into_descriptors(); 60 61 self.socket 62 .send_with_fds(&[IoSlice::new(&msg_json)], &msg_descriptors) 63 .map_err(Error::Send)?; 64 Ok(()) 65 } 66 recv<T: DeserializeOwned>(&self) -> Result<T>67 pub fn recv<T: DeserializeOwned>(&self) -> Result<T> { 68 let (msg_json, msg_descriptors) = 69 self.socket.recv_as_vec_with_fds().map_err(Error::Recv)?; 70 71 if msg_json.is_empty() { 72 return Err(Error::Disconnected); 73 } 74 75 let mut msg_descriptors_safe = msg_descriptors 76 .into_iter() 77 .map(|v| { 78 Some(unsafe { 79 // Safe because the socket returns new fds that are owned locally by this scope. 80 SafeDescriptor::from_raw_descriptor(v) 81 }) 82 }) 83 .collect(); 84 85 deserialize_with_descriptors( 86 || serde_json::from_slice(&msg_json), 87 &mut msg_descriptors_safe, 88 ) 89 .map_err(Error::Json) 90 } 91 set_send_timeout(&self, timeout: Option<Duration>) -> Result<()>92 pub fn set_send_timeout(&self, timeout: Option<Duration>) -> Result<()> { 93 self.socket 94 .set_write_timeout(timeout) 95 .map_err(Error::SetSendTimeout) 96 } 97 set_recv_timeout(&self, timeout: Option<Duration>) -> Result<()>98 pub fn set_recv_timeout(&self, timeout: Option<Duration>) -> Result<()> { 99 self.socket 100 .set_read_timeout(timeout) 101 .map_err(Error::SetRecvTimeout) 102 } 103 } 104 105 impl AsRawDescriptor for Tube { as_raw_descriptor(&self) -> RawDescriptor106 fn as_raw_descriptor(&self) -> RawDescriptor { 107 self.socket.as_raw_descriptor() 108 } 109 } 110 111 impl AsRawFd for Tube { as_raw_fd(&self) -> RawFd112 fn as_raw_fd(&self) -> RawFd { 113 self.socket.as_raw_fd() 114 } 115 } 116 117 impl ReadNotifier for Tube { get_read_notifier(&self) -> &dyn AsRawDescriptor118 fn get_read_notifier(&self) -> &dyn AsRawDescriptor { 119 &self.socket 120 } 121 } 122 123 impl FromRawDescriptor for Tube { 124 /// # Safety: 125 /// Requirements: 126 /// (1) The caller owns rd. 127 /// (2) When the call completes, ownership of rd has transferred to the returned value. from_raw_descriptor(rd: RawDescriptor) -> Self128 unsafe fn from_raw_descriptor(rd: RawDescriptor) -> Self { 129 Self { 130 socket: UnixSeqpacket::from_raw_descriptor(rd), 131 _unsync_marker: PhantomData, 132 } 133 } 134 } 135 136 impl AsRawFd for SendTube { as_raw_fd(&self) -> RawFd137 fn as_raw_fd(&self) -> RawFd { 138 self.0.as_raw_descriptor() 139 } 140 } 141 142 impl AsRawFd for RecvTube { as_raw_fd(&self) -> RawFd143 fn as_raw_fd(&self) -> RawFd { 144 self.0.as_raw_descriptor() 145 } 146 } 147