Private
Public Access
1
0

xpc: Use reply port when replying to RPC messages

This commit is contained in:
2025-08-24 15:28:33 -07:00
parent 06b27c041a
commit a93a773071
5 changed files with 205 additions and 212 deletions

View File

@@ -78,6 +78,23 @@ impl XPCClient {
xpc_release(xpc_object);
}
}
pub fn send_message_with_reply(&self, message: Message) -> Message {
use xpc_connection::message_to_xpc_object;
use xpc_connection::xpc_object_to_message;
use xpc_connection_sys::{xpc_connection_send_message_with_reply_sync, xpc_release};
unsafe {
let xobj = message_to_xpc_object(message);
let reply = xpc_connection_send_message_with_reply_sync(self.connection, xobj);
xpc_release(xobj);
let msg = xpc_object_to_message(reply);
if !reply.is_null() {
xpc_release(reply);
}
msg
}
}
}
impl Drop for XPCClient {
@@ -147,12 +164,10 @@ impl XpcDaemonInterface {
args: Option<HashMap<CString, Message>>,
) -> anyhow::Result<HashMap<CString, Message>> {
let request = Self::build_request(method, args);
client.send_message(Message::Dictionary(request));
match client.next().await {
Some(Message::Dictionary(map)) => Ok(map),
Some(other) => Err(anyhow::anyhow!("Unexpected XPC reply: {:?}", other)),
None => Err(anyhow::anyhow!("No reply received from XPC daemon")),
let reply = client.send_message_with_reply(Message::Dictionary(request));
match reply {
Message::Dictionary(map) => Ok(map),
other => Err(anyhow::anyhow!("Unexpected XPC reply: {:?}", other)),
}
}
@@ -384,7 +399,8 @@ impl DaemonInterface for XpcDaemonInterface {
let mach_port_name = Self::build_service_name()?;
let mut client = XPCClient::connect(&mach_port_name);
// Send a subscription/warm-up message so the server loop starts selecting for this client
// Subscribe to begin receiving signals on this connection
eprintln!("[kpcli] Sending SubscribeSignals");
client.send_message(Message::Dictionary(Self::build_request(
"SubscribeSignals",
None,
@@ -394,6 +410,7 @@ impl DaemonInterface for XpcDaemonInterface {
while let Some(msg) = client.next().await {
match msg {
Message::Dictionary(map) => {
eprintln!("[kpcli] Received signal dictionary");
let name_key = Self::key("name");
let args_key = Self::key("arguments");
let name = match map.get(&name_key) {
@@ -476,8 +493,13 @@ impl DaemonInterface for XpcDaemonInterface {
_ => {}
}
}
Message::Error(xpc_connection::MessageError::ConnectionInvalid) => break,
_ => {}
Message::Error(xpc_connection::MessageError::ConnectionInvalid) => {
eprintln!("[kpcli] XPC connection invalid");
break
}
other => {
eprintln!("[kpcli] Unexpected XPC message: {:?}", other);
}
}
}
Ok(())