1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::mem; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::ManuallyDrop; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc; 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 11*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 12*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serializer; 13*bb4ee6a4SAndroid Build Coastguard Worker 14*bb4ee6a4SAndroid Build Coastguard Worker use crate::EventToken; 15*bb4ee6a4SAndroid Build Coastguard Worker use crate::RawDescriptor; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker /// Wraps a RawDescriptor and safely closes it when self falls out of scope. 18*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Serialize, Deserialize, Debug, Eq)] 19*bb4ee6a4SAndroid Build Coastguard Worker #[serde(transparent)] 20*bb4ee6a4SAndroid Build Coastguard Worker pub struct SafeDescriptor { 21*bb4ee6a4SAndroid Build Coastguard Worker #[serde(with = "super::with_raw_descriptor")] 22*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) descriptor: RawDescriptor, 23*bb4ee6a4SAndroid Build Coastguard Worker } 24*bb4ee6a4SAndroid Build Coastguard Worker 25*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for forfeiting ownership of the current raw descriptor, and returning the raw descriptor 26*bb4ee6a4SAndroid Build Coastguard Worker pub trait IntoRawDescriptor { into_raw_descriptor(self) -> RawDescriptor27*bb4ee6a4SAndroid Build Coastguard Worker fn into_raw_descriptor(self) -> RawDescriptor; 28*bb4ee6a4SAndroid Build Coastguard Worker } 29*bb4ee6a4SAndroid Build Coastguard Worker 30*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for returning the underlying raw descriptor, without giving up ownership of the 31*bb4ee6a4SAndroid Build Coastguard Worker /// descriptor. 32*bb4ee6a4SAndroid Build Coastguard Worker pub trait AsRawDescriptor { 33*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the underlying raw descriptor. 34*bb4ee6a4SAndroid Build Coastguard Worker /// 35*bb4ee6a4SAndroid Build Coastguard Worker /// Since the descriptor is still owned by the provider, callers should not assume that it will 36*bb4ee6a4SAndroid Build Coastguard Worker /// remain open for longer than the immediate call of this method. In particular, it is a 37*bb4ee6a4SAndroid Build Coastguard Worker /// dangerous practice to store the result of this method for future use: instead, it should be 38*bb4ee6a4SAndroid Build Coastguard Worker /// used to e.g. obtain a raw descriptor that is immediately passed to a system call. 39*bb4ee6a4SAndroid Build Coastguard Worker /// 40*bb4ee6a4SAndroid Build Coastguard Worker /// If you need to use the descriptor for a longer time (and particularly if you cannot reliably 41*bb4ee6a4SAndroid Build Coastguard Worker /// track the lifetime of the providing object), you should probably consider using 42*bb4ee6a4SAndroid Build Coastguard Worker /// [`SafeDescriptor`] (possibly along with [`trait@IntoRawDescriptor`]) to get full ownership 43*bb4ee6a4SAndroid Build Coastguard Worker /// over a descriptor pointing to the same resource. as_raw_descriptor(&self) -> RawDescriptor44*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor; 45*bb4ee6a4SAndroid Build Coastguard Worker } 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker /// A trait similar to `AsRawDescriptor` but supports an arbitrary number of descriptors. 48*bb4ee6a4SAndroid Build Coastguard Worker pub trait AsRawDescriptors { 49*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the underlying raw descriptors. 50*bb4ee6a4SAndroid Build Coastguard Worker /// 51*bb4ee6a4SAndroid Build Coastguard Worker /// Please refer to the documentation of [`AsRawDescriptor::as_raw_descriptor`] for limitations 52*bb4ee6a4SAndroid Build Coastguard Worker /// and recommended use. as_raw_descriptors(&self) -> Vec<RawDescriptor>53*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptors(&self) -> Vec<RawDescriptor>; 54*bb4ee6a4SAndroid Build Coastguard Worker } 55*bb4ee6a4SAndroid Build Coastguard Worker 56*bb4ee6a4SAndroid Build Coastguard Worker pub trait FromRawDescriptor { 57*bb4ee6a4SAndroid Build Coastguard Worker /// # Safety 58*bb4ee6a4SAndroid Build Coastguard Worker /// Safe only if the caller ensures nothing has access to the descriptor after passing it to 59*bb4ee6a4SAndroid Build Coastguard Worker /// `from_raw_descriptor` from_raw_descriptor(descriptor: RawDescriptor) -> Self60*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self; 61*bb4ee6a4SAndroid Build Coastguard Worker } 62*bb4ee6a4SAndroid Build Coastguard Worker 63*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for SafeDescriptor { as_raw_descriptor(&self) -> RawDescriptor64*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 65*bb4ee6a4SAndroid Build Coastguard Worker self.descriptor 66*bb4ee6a4SAndroid Build Coastguard Worker } 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRawDescriptor for Arc<T> 70*bb4ee6a4SAndroid Build Coastguard Worker where 71*bb4ee6a4SAndroid Build Coastguard Worker T: AsRawDescriptor, 72*bb4ee6a4SAndroid Build Coastguard Worker { as_raw_descriptor(&self) -> RawDescriptor73*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 74*bb4ee6a4SAndroid Build Coastguard Worker self.as_ref().as_raw_descriptor() 75*bb4ee6a4SAndroid Build Coastguard Worker } 76*bb4ee6a4SAndroid Build Coastguard Worker } 77*bb4ee6a4SAndroid Build Coastguard Worker 78*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRawDescriptors for T 79*bb4ee6a4SAndroid Build Coastguard Worker where 80*bb4ee6a4SAndroid Build Coastguard Worker T: AsRawDescriptor, 81*bb4ee6a4SAndroid Build Coastguard Worker { as_raw_descriptors(&self) -> Vec<RawDescriptor>82*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptors(&self) -> Vec<RawDescriptor> { 83*bb4ee6a4SAndroid Build Coastguard Worker vec![self.as_raw_descriptor()] 84*bb4ee6a4SAndroid Build Coastguard Worker } 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker 87*bb4ee6a4SAndroid Build Coastguard Worker impl IntoRawDescriptor for SafeDescriptor { into_raw_descriptor(self) -> RawDescriptor88*bb4ee6a4SAndroid Build Coastguard Worker fn into_raw_descriptor(self) -> RawDescriptor { 89*bb4ee6a4SAndroid Build Coastguard Worker let descriptor = self.descriptor; 90*bb4ee6a4SAndroid Build Coastguard Worker mem::forget(self); 91*bb4ee6a4SAndroid Build Coastguard Worker descriptor 92*bb4ee6a4SAndroid Build Coastguard Worker } 93*bb4ee6a4SAndroid Build Coastguard Worker } 94*bb4ee6a4SAndroid Build Coastguard Worker 95*bb4ee6a4SAndroid Build Coastguard Worker impl FromRawDescriptor for SafeDescriptor { from_raw_descriptor(descriptor: RawDescriptor) -> Self96*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self { 97*bb4ee6a4SAndroid Build Coastguard Worker SafeDescriptor { descriptor } 98*bb4ee6a4SAndroid Build Coastguard Worker } 99*bb4ee6a4SAndroid Build Coastguard Worker } 100*bb4ee6a4SAndroid Build Coastguard Worker 101*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<&dyn AsRawDescriptor> for SafeDescriptor { 102*bb4ee6a4SAndroid Build Coastguard Worker type Error = std::io::Error; 103*bb4ee6a4SAndroid Build Coastguard Worker 104*bb4ee6a4SAndroid Build Coastguard Worker /// Clones the underlying descriptor (handle), internally creating a new descriptor. 105*bb4ee6a4SAndroid Build Coastguard Worker /// 106*bb4ee6a4SAndroid Build Coastguard Worker /// WARNING: Windows does NOT support cloning/duplicating all types of handles. DO NOT use this 107*bb4ee6a4SAndroid Build Coastguard Worker /// function on IO completion ports, sockets, or pseudo-handles (except those from 108*bb4ee6a4SAndroid Build Coastguard Worker /// GetCurrentProcess or GetCurrentThread). See 109*bb4ee6a4SAndroid Build Coastguard Worker /// <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle> 110*bb4ee6a4SAndroid Build Coastguard Worker /// for further details. 111*bb4ee6a4SAndroid Build Coastguard Worker /// 112*bb4ee6a4SAndroid Build Coastguard Worker /// TODO(b/191800567): this API has sharp edges on Windows. We should evaluate making some 113*bb4ee6a4SAndroid Build Coastguard Worker /// adjustments to smooth those edges. try_from(rd: &dyn AsRawDescriptor) -> std::result::Result<Self, Self::Error>114*bb4ee6a4SAndroid Build Coastguard Worker fn try_from(rd: &dyn AsRawDescriptor) -> std::result::Result<Self, Self::Error> { 115*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 116*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the underlying raw descriptor is guaranteed valid by rd's existence. 117*bb4ee6a4SAndroid Build Coastguard Worker // 118*bb4ee6a4SAndroid Build Coastguard Worker // Note that we are cloning the underlying raw descriptor since we have no guarantee of 119*bb4ee6a4SAndroid Build Coastguard Worker // its existence after this function returns. 120*bb4ee6a4SAndroid Build Coastguard Worker let rd_as_safe_desc = ManuallyDrop::new(unsafe { 121*bb4ee6a4SAndroid Build Coastguard Worker SafeDescriptor::from_raw_descriptor(rd.as_raw_descriptor()) 122*bb4ee6a4SAndroid Build Coastguard Worker }); 123*bb4ee6a4SAndroid Build Coastguard Worker 124*bb4ee6a4SAndroid Build Coastguard Worker // We have to clone rd because we have no guarantee ownership was transferred (rd is 125*bb4ee6a4SAndroid Build Coastguard Worker // borrowed). 126*bb4ee6a4SAndroid Build Coastguard Worker rd_as_safe_desc 127*bb4ee6a4SAndroid Build Coastguard Worker .try_clone() 128*bb4ee6a4SAndroid Build Coastguard Worker .map_err(|e| Self::Error::from_raw_os_error(e.errno())) 129*bb4ee6a4SAndroid Build Coastguard Worker } 130*bb4ee6a4SAndroid Build Coastguard Worker } 131*bb4ee6a4SAndroid Build Coastguard Worker 132*bb4ee6a4SAndroid Build Coastguard Worker impl From<File> for SafeDescriptor { from(f: File) -> SafeDescriptor133*bb4ee6a4SAndroid Build Coastguard Worker fn from(f: File) -> SafeDescriptor { 134*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 135*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we own the File at this point. 136*bb4ee6a4SAndroid Build Coastguard Worker unsafe { SafeDescriptor::from_raw_descriptor(f.into_raw_descriptor()) } 137*bb4ee6a4SAndroid Build Coastguard Worker } 138*bb4ee6a4SAndroid Build Coastguard Worker } 139*bb4ee6a4SAndroid Build Coastguard Worker 140*bb4ee6a4SAndroid Build Coastguard Worker /// For use cases where a simple wrapper around a [`RawDescriptor`] is needed, in order to e.g. 141*bb4ee6a4SAndroid Build Coastguard Worker /// implement [`trait@AsRawDescriptor`]. 142*bb4ee6a4SAndroid Build Coastguard Worker /// 143*bb4ee6a4SAndroid Build Coastguard Worker /// This is a simply a wrapper and does not manage the lifetime of the descriptor. As such it is the 144*bb4ee6a4SAndroid Build Coastguard Worker /// responsibility of the user to ensure that the wrapped descriptor will not be closed for as long 145*bb4ee6a4SAndroid Build Coastguard Worker /// as the `Descriptor` is alive. 146*bb4ee6a4SAndroid Build Coastguard Worker /// 147*bb4ee6a4SAndroid Build Coastguard Worker /// Most use-cases should prefer [`SafeDescriptor`] or implementing and using 148*bb4ee6a4SAndroid Build Coastguard Worker /// [`trait@AsRawDescriptor`] on the type providing the descriptor. Using this wrapper usually means 149*bb4ee6a4SAndroid Build Coastguard Worker /// something can be improved in your code. 150*bb4ee6a4SAndroid Build Coastguard Worker /// 151*bb4ee6a4SAndroid Build Coastguard Worker /// Valid uses of this struct include: 152*bb4ee6a4SAndroid Build Coastguard Worker /// * You only have a valid [`RawDescriptor`] and need to pass something that implements 153*bb4ee6a4SAndroid Build Coastguard Worker /// [`trait@AsRawDescriptor`] to a function, 154*bb4ee6a4SAndroid Build Coastguard Worker /// * You need to serialize a [`RawDescriptor`], 155*bb4ee6a4SAndroid Build Coastguard Worker /// * You need [`trait@Send`] or [`trait@Sync`] for your descriptor and properly handle the case 156*bb4ee6a4SAndroid Build Coastguard Worker /// where your descriptor gets closed. 157*bb4ee6a4SAndroid Build Coastguard Worker /// 158*bb4ee6a4SAndroid Build Coastguard Worker /// Note that with the exception of the last use-case (which requires proper error checking against 159*bb4ee6a4SAndroid Build Coastguard Worker /// the descriptor being closed), the `Descriptor` instance would be very short-lived. 160*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] 161*bb4ee6a4SAndroid Build Coastguard Worker #[repr(transparent)] 162*bb4ee6a4SAndroid Build Coastguard Worker pub struct Descriptor(pub RawDescriptor); 163*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Descriptor { as_raw_descriptor(&self) -> RawDescriptor164*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 165*bb4ee6a4SAndroid Build Coastguard Worker self.0 166*bb4ee6a4SAndroid Build Coastguard Worker } 167*bb4ee6a4SAndroid Build Coastguard Worker } 168*bb4ee6a4SAndroid Build Coastguard Worker impl FromRawDescriptor for Descriptor { from_raw_descriptor(desc: RawDescriptor) -> Self169*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn from_raw_descriptor(desc: RawDescriptor) -> Self { 170*bb4ee6a4SAndroid Build Coastguard Worker Descriptor(desc) 171*bb4ee6a4SAndroid Build Coastguard Worker } 172*bb4ee6a4SAndroid Build Coastguard Worker } 173*bb4ee6a4SAndroid Build Coastguard Worker 174*bb4ee6a4SAndroid Build Coastguard Worker /// Implement token for implementations that wish to use this struct as such 175*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for Descriptor { as_raw_token(&self) -> u64176*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_token(&self) -> u64 { 177*bb4ee6a4SAndroid Build Coastguard Worker self.0 as u64 178*bb4ee6a4SAndroid Build Coastguard Worker } 179*bb4ee6a4SAndroid Build Coastguard Worker from_raw_token(data: u64) -> Self180*bb4ee6a4SAndroid Build Coastguard Worker fn from_raw_token(data: u64) -> Self { 181*bb4ee6a4SAndroid Build Coastguard Worker Descriptor(data as RawDescriptor) 182*bb4ee6a4SAndroid Build Coastguard Worker } 183*bb4ee6a4SAndroid Build Coastguard Worker } 184*bb4ee6a4SAndroid Build Coastguard Worker 185*bb4ee6a4SAndroid Build Coastguard Worker impl Serialize for Descriptor { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,186*bb4ee6a4SAndroid Build Coastguard Worker fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 187*bb4ee6a4SAndroid Build Coastguard Worker where 188*bb4ee6a4SAndroid Build Coastguard Worker S: Serializer, 189*bb4ee6a4SAndroid Build Coastguard Worker { 190*bb4ee6a4SAndroid Build Coastguard Worker serializer.serialize_u64(self.0 as u64) 191*bb4ee6a4SAndroid Build Coastguard Worker } 192*bb4ee6a4SAndroid Build Coastguard Worker } 193*bb4ee6a4SAndroid Build Coastguard Worker 194*bb4ee6a4SAndroid Build Coastguard Worker impl<'de> Deserialize<'de> for Descriptor { deserialize<D>(deserializer: D) -> Result<Descriptor, D::Error> where D: serde::Deserializer<'de>,195*bb4ee6a4SAndroid Build Coastguard Worker fn deserialize<D>(deserializer: D) -> Result<Descriptor, D::Error> 196*bb4ee6a4SAndroid Build Coastguard Worker where 197*bb4ee6a4SAndroid Build Coastguard Worker D: serde::Deserializer<'de>, 198*bb4ee6a4SAndroid Build Coastguard Worker { 199*bb4ee6a4SAndroid Build Coastguard Worker u64::deserialize(deserializer).map(|data| Descriptor(data as RawDescriptor)) 200*bb4ee6a4SAndroid Build Coastguard Worker } 201*bb4ee6a4SAndroid Build Coastguard Worker } 202