at master 2.7 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3// Copyright (C) 2025 Google LLC. 4 5use kernel::fmt; 6use kernel::prelude::*; 7 8use crate::defs::*; 9 10pub(crate) type BinderResult<T = ()> = core::result::Result<T, BinderError>; 11 12/// An error that will be returned to userspace via the `BINDER_WRITE_READ` ioctl rather than via 13/// errno. 14pub(crate) struct BinderError { 15 pub(crate) reply: u32, 16 source: Option<Error>, 17} 18 19impl BinderError { 20 pub(crate) fn new_dead() -> Self { 21 Self { 22 reply: BR_DEAD_REPLY, 23 source: None, 24 } 25 } 26 27 pub(crate) fn new_frozen() -> Self { 28 Self { 29 reply: BR_FROZEN_REPLY, 30 source: None, 31 } 32 } 33 34 pub(crate) fn new_frozen_oneway() -> Self { 35 Self { 36 reply: BR_TRANSACTION_PENDING_FROZEN, 37 source: None, 38 } 39 } 40 41 pub(crate) fn is_dead(&self) -> bool { 42 self.reply == BR_DEAD_REPLY 43 } 44 45 pub(crate) fn as_errno(&self) -> kernel::ffi::c_int { 46 self.source.unwrap_or(EINVAL).to_errno() 47 } 48 49 pub(crate) fn should_pr_warn(&self) -> bool { 50 self.source.is_some() 51 } 52} 53 54/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno 55/// should be stored as the thread's extended error when given to userspace. 56impl From<Error> for BinderError { 57 fn from(source: Error) -> Self { 58 Self { 59 reply: BR_FAILED_REPLY, 60 source: Some(source), 61 } 62 } 63} 64 65impl From<kernel::fs::file::BadFdError> for BinderError { 66 fn from(source: kernel::fs::file::BadFdError) -> Self { 67 BinderError::from(Error::from(source)) 68 } 69} 70 71impl From<kernel::alloc::AllocError> for BinderError { 72 fn from(_: kernel::alloc::AllocError) -> Self { 73 Self { 74 reply: BR_FAILED_REPLY, 75 source: Some(ENOMEM), 76 } 77 } 78} 79 80impl fmt::Debug for BinderError { 81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 82 match self.reply { 83 BR_FAILED_REPLY => match self.source.as_ref() { 84 Some(source) => f 85 .debug_struct("BR_FAILED_REPLY") 86 .field("source", source) 87 .finish(), 88 None => f.pad("BR_FAILED_REPLY"), 89 }, 90 BR_DEAD_REPLY => f.pad("BR_DEAD_REPLY"), 91 BR_FROZEN_REPLY => f.pad("BR_FROZEN_REPLY"), 92 BR_TRANSACTION_PENDING_FROZEN => f.pad("BR_TRANSACTION_PENDING_FROZEN"), 93 BR_TRANSACTION_COMPLETE => f.pad("BR_TRANSACTION_COMPLETE"), 94 _ => f 95 .debug_struct("BinderError") 96 .field("reply", &self.reply) 97 .finish(), 98 } 99 } 100}