1
0
Fork 0
forked from wry/wry

config: add comm client criteria

This commit is contained in:
Julian Orth 2025-05-03 13:03:48 +02:00
parent bdabb7bbdd
commit cc734a135c
12 changed files with 73 additions and 2 deletions

View file

@ -92,4 +92,5 @@ pub enum ClientCriterionStringField {
SandboxEngine,
SandboxAppId,
SandboxInstanceId,
Comm,
}

View file

@ -1545,6 +1545,8 @@ impl ConfigClient {
ClientCriterion::Uid(p) => ClientCriterionIpc::Uid(p),
ClientCriterion::Pid(p) => ClientCriterionIpc::Pid(p),
ClientCriterion::IsXwayland => ClientCriterionIpc::IsXwayland,
ClientCriterion::Comm(t) => string!(t, Comm, false),
ClientCriterion::CommRegex(t) => string!(t, Comm, true),
};
let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion });
get_response!(

View file

@ -83,6 +83,10 @@ pub enum ClientCriterion<'a> {
Pid(i32),
/// Matches if the client is Xwayland.
IsXwayland,
/// Matches the `/proc/pid/comm` of the client verbatim.
Comm(&'a str),
/// Matches the `/proc/pid/comm` of the client with a regular expression.
CommRegex(&'a str),
}
impl ClientCriterion<'_> {

View file

@ -1882,6 +1882,7 @@ impl ConfigProxyHandler {
ClientCriterionStringField::SandboxInstanceId => {
mgr.sandbox_instance_id(needle)
}
ClientCriterionStringField::Comm => mgr.comm(needle),
}
}
ClientCriterionIpc::Sandboxed => mgr.sandboxed(),

View file

@ -11,7 +11,8 @@ use {
clmm_pid::ClmMatchPid,
clmm_sandboxed::ClmMatchSandboxed,
clmm_string::{
ClmMatchSandboxAppId, ClmMatchSandboxEngine, ClmMatchSandboxInstanceId,
ClmMatchComm, ClmMatchSandboxAppId, ClmMatchSandboxEngine,
ClmMatchSandboxInstanceId,
},
clmm_uid::ClmMatchUid,
},
@ -58,6 +59,7 @@ pub struct RootMatchers {
sandbox_instance_id: ClmRootMatcherMap<ClmMatchSandboxInstanceId>,
uid: ClmRootMatcherMap<ClmMatchUid>,
pid: ClmRootMatcherMap<ClmMatchPid>,
comm: ClmRootMatcherMap<ClmMatchComm>,
}
pub async fn handle_cl_changes(state: Rc<State>) {
@ -160,6 +162,7 @@ impl ClMatcherManager {
unconditional!(sandbox_engine);
unconditional!(uid);
unconditional!(pid);
unconditional!(comm);
fixed!(sandboxed);
fixed!(is_xwayland);
self.constant[true].handle(data);
@ -193,6 +196,10 @@ impl ClMatcherManager {
pub fn is_xwayland(&self) -> Rc<ClmUpstreamNode> {
self.is_xwayland[true].clone()
}
pub fn comm(&self, string: CritLiteralOrRegex) -> Rc<ClmUpstreamNode> {
self.root(ClmMatchComm::new(string))
}
}
impl CritTarget for Rc<Client> {

View file

@ -15,8 +15,10 @@ pub type ClmMatchString<T> = CritMatchString<Rc<Client>, T>;
pub type ClmMatchSandboxEngine = ClmMatchString<AcceptorMetadataAccess<SandboxEngineField>>;
pub type ClmMatchSandboxAppId = ClmMatchString<AcceptorMetadataAccess<SandboxAppIdField>>;
pub type ClmMatchSandboxInstanceId = ClmMatchString<AcceptorMetadataAccess<SandboxInstanceIdField>>;
pub type ClmMatchComm = ClmMatchString<CommAccess>;
pub struct AcceptorMetadataAccess<T>(PhantomData<T>);
pub struct CommAccess;
trait SandboxField: Sized + 'static {
fn field(meta: &AcceptorMetadata) -> &Option<String>;
@ -77,3 +79,13 @@ impl SandboxField for SandboxInstanceIdField {
&roots.sandbox_instance_id
}
}
impl StringAccess<Rc<Client>> for CommAccess {
fn with_string(data: &Rc<Client>, f: impl FnOnce(&str) -> bool) -> bool {
f(&data.pid_info.comm)
}
fn nodes(roots: &RootMatchers) -> &ClmRootMatcherMap<ClmMatchString<Self>> {
&roots.comm
}
}

View file

@ -235,6 +235,8 @@ pub struct ClientMatch {
pub uid: Option<i32>,
pub pid: Option<i32>,
pub is_xwayland: Option<bool>,
pub comm: Option<String>,
pub comm_regex: Option<String>,
}
#[derive(Debug, Clone)]

View file

@ -49,7 +49,15 @@ impl Parser for ClientMatchParser<'_> {
sandbox_app_id,
sandbox_app_id_regex,
),
(sandbox_instance_id, sandbox_instance_id_regex, uid, pid, is_xwayland),
(
sandbox_instance_id,
sandbox_instance_id_regex,
uid,
pid,
is_xwayland,
comm,
comm_regex,
),
) = ext.extract((
(
opt(str("name")),
@ -69,6 +77,8 @@ impl Parser for ClientMatchParser<'_> {
opt(s32("uid")),
opt(s32("pid")),
opt(bol("is-xwayland")),
opt(str("comm")),
opt(str("comm-regex")),
),
))?;
let mut not = None;
@ -112,6 +122,8 @@ impl Parser for ClientMatchParser<'_> {
uid: uid.despan(),
pid: pid.despan(),
is_xwayland: is_xwayland.despan(),
comm: comm.despan_into(),
comm_regex: comm_regex.despan_into(),
})
}
}

View file

@ -120,6 +120,8 @@ impl Rule for ClientRule {
value_ref!(SandboxAppIdRegex, sandbox_app_id_regex);
value_ref!(SandboxInstanceId, sandbox_instance_id);
value_ref!(SandboxInstanceIdRegex, sandbox_instance_id_regex);
value_ref!(Comm, comm);
value_ref!(CommRegex, comm_regex);
value!(Uid, uid);
value!(Pid, pid);
bool!(Sandboxed, sandboxed);

View file

@ -571,6 +571,14 @@
"is-xwayland": {
"type": "boolean",
"description": "Matches if the client is/isn't Xwayland."
},
"comm": {
"type": "string",
"description": "Matches the `/proc/pid/comm` of the client verbatim."
},
"comm-regex": {
"type": "string",
"description": "Matches the `/proc/pid/comm` of the client with a regular expression."
}
},
"required": []

View file

@ -893,6 +893,18 @@ The table has the following fields:
The value of this field should be a boolean.
- `comm` (optional):
Matches the `/proc/pid/comm` of the client verbatim.
The value of this field should be a string.
- `comm-regex` (optional):
Matches the `/proc/pid/comm` of the client with a regular expression.
The value of this field should be a string.
<a name="types-ClientMatchExactly"></a>
### `ClientMatchExactly`

View file

@ -3251,6 +3251,14 @@ ClientMatch:
kind: boolean
required: false
description: Matches if the client is/isn't Xwayland.
comm:
kind: string
required: false
description: Matches the `/proc/pid/comm` of the client verbatim.
comm-regex:
kind: string
required: false
description: Matches the `/proc/pid/comm` of the client with a regular expression.
ClientMatchExactly: