• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 use alloc::alloc::AllocError;
18 use alloc::collections::TryReserveError;
19 use core::num::TryFromIntError;
20 use trusty_std::ffi::TryNewError;
21 use trusty_sys::{c_long, Error};
22 
23 /// A specialized [`Result`] type for IPC operations.
24 ///
25 /// This type is used throughout the [`tipc`](crate) crate as a shorthand for result
26 /// return values. Users outside the current crate should generally use this
27 /// type as `tipc::Result` rather than shadowing the standard `Result` type.
28 pub type Result<T> = core::result::Result<T, TipcError>;
29 
30 /// Errors that an IPC connection may encounter.
31 #[derive(Clone, Debug, Eq, PartialEq)]
32 pub enum TipcError {
33     /// The handle ID provided or returned by the kernel was invalid.
34     InvalidHandle,
35 
36     /// The provided port was invalid.
37     InvalidPort,
38 
39     /// Failed to allocate, probably out of memory.
40     AllocError,
41 
42     /// An integer did not fit into the required size.
43     OutOfBounds,
44 
45     /// Could not write the entire message. Contains the number of bytes that
46     /// were successfully written.
47     IncompleteWrite { num_bytes_written: usize },
48 
49     /// The provided buffer was not large enough to receive the entire message.
50     NotEnoughBuffer,
51 
52     /// Some other error occurred.
53     UnknownError,
54 
55     /// Internal data was not valid
56     InvalidData,
57 
58     /// Message could not be sent because connection was busy.
59     Busy,
60 
61     /// The channel was closed before the operation could be completed.
62     ChannelClosed,
63 
64     /// Some other system error
65     SystemError(Error),
66 }
67 
68 /// The result type for an `on_connect` operation.
69 ///
70 /// If the connection is accepted, contains created connection object for this connection.
71 #[derive(Clone, Copy, Debug)]
72 pub enum ConnectResult<C> {
73     Accept(C),
74     CloseConnection,
75 }
76 
77 /// The result type for an `on_message` operation.
78 ///
79 /// Its value tells the `ServiceManager` what to do after handling the message.
80 #[derive(Clone, Copy, Debug)]
81 pub enum MessageResult {
82     MaintainConnection,
83     CloseConnection,
84 }
85 
86 impl TipcError {
from_uapi(rc: c_long) -> Self87     pub fn from_uapi(rc: c_long) -> Self {
88         let sys_err: Error = rc.into();
89         match sys_err {
90             Error::BadHandle => TipcError::InvalidHandle,
91             e => TipcError::SystemError(e),
92         }
93     }
94 }
95 
96 impl<T> ConnectResult<T> {
97     /// Maps a `ConnectResult<T>` to a `ConnectResult<U>` by applying a function to the contained connection.
map<U, F: FnOnce(T) -> U>(self, f: F) -> ConnectResult<U>98     pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> ConnectResult<U> {
99         match self {
100             Self::Accept(c) => ConnectResult::Accept(f(c)),
101             Self::CloseConnection => ConnectResult::CloseConnection,
102         }
103     }
104 }
105 
106 impl From<TryNewError> for TipcError {
from(err: TryNewError) -> Self107     fn from(err: TryNewError) -> Self {
108         match err {
109             TryNewError::NulError(..) => Self::InvalidPort,
110             TryNewError::AllocError => Self::AllocError,
111         }
112     }
113 }
114 
115 impl From<TryReserveError> for TipcError {
from(_err: TryReserveError) -> Self116     fn from(_err: TryReserveError) -> Self {
117         TipcError::AllocError
118     }
119 }
120 
121 impl From<TryFromIntError> for TipcError {
from(_err: TryFromIntError) -> Self122     fn from(_err: TryFromIntError) -> Self {
123         TipcError::OutOfBounds
124     }
125 }
126 
127 impl From<AllocError> for TipcError {
from(_err: AllocError) -> Self128     fn from(_err: AllocError) -> Self {
129         TipcError::AllocError
130     }
131 }
132