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