Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/android/binder/error.rs
49181 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
// Copyright (C) 2025 Google LLC.
4
5
use kernel::fmt;
6
use kernel::prelude::*;
7
8
use crate::defs::*;
9
10
pub(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.
14
pub(crate) struct BinderError {
15
pub(crate) reply: u32,
16
source: Option<Error>,
17
}
18
19
impl 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.
56
impl 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
65
impl 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
71
impl 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
80
impl 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
}
101
102