autocommit 2022-03-02 14:24:07 CET
This commit is contained in:
parent
0e9afcbfa5
commit
aa0cb94143
30 changed files with 1059 additions and 123 deletions
|
|
@ -86,7 +86,7 @@ impl Auth {
|
|||
match uapi::read(self.socket.fd.raw(), &mut self.buf[..]) {
|
||||
Ok(n) => self.buf_stop = n.len(),
|
||||
Err(Errno(c::EAGAIN)) => {
|
||||
let _ = self.socket.fd.readable().await;
|
||||
self.socket.fd.readable().await?;
|
||||
}
|
||||
Err(e) => return Err(DbusError::ReadError(e.into())),
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ impl Auth {
|
|||
match uapi::write(self.socket.fd.raw(), &buf[start..]) {
|
||||
Ok(n) => start += n,
|
||||
Err(Errno(c::EAGAIN)) => {
|
||||
let _ = self.socket.fd.writable().await;
|
||||
self.socket.fd.writable().await?;
|
||||
}
|
||||
Err(e) => return Err(DbusError::WriteError(e.into())),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ impl DynamicType {
|
|||
DynamicType::U32 => Variant::U32(parser.read_pod()?),
|
||||
DynamicType::I64 => Variant::I64(parser.read_pod()?),
|
||||
DynamicType::U64 => Variant::U64(parser.read_pod()?),
|
||||
DynamicType::F64 => Variant::F64(parser.read_pod()?),
|
||||
DynamicType::F64 => Variant::F64(f64::from_bits(parser.read_pod()?)),
|
||||
DynamicType::String => Variant::String(parser.read_string()?),
|
||||
DynamicType::ObjectPath => Variant::ObjectPath(parser.read_object_path()?),
|
||||
DynamicType::Signature => Variant::Signature(parser.read_signature()?),
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ fn connect(
|
|||
dead: Cell::new(false),
|
||||
headers: Default::default(),
|
||||
run_toplevel: run_toplevel.clone(),
|
||||
signal_handlers: Default::default(),
|
||||
});
|
||||
let skt = socket.clone();
|
||||
socket.call(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use super::{
|
|||
HDR_SENDER, HDR_SIGNATURE, HDR_UNIX_FDS,
|
||||
};
|
||||
use crate::dbus::{
|
||||
CallError, DbusError, DbusSocket, Headers, Parser, MSG_ERROR, MSG_METHOD_RETURN,
|
||||
CallError, DbusError, DbusSocket, Headers, Parser, MSG_ERROR, MSG_METHOD_RETURN, MSG_SIGNAL,
|
||||
};
|
||||
use crate::utils::ptr_ext::{MutPtrExt, PtrExt};
|
||||
use crate::ErrorFmt;
|
||||
|
|
@ -119,8 +119,8 @@ impl Incoming {
|
|||
log::error!(
|
||||
"{}: Message reply has an invalid signature: expected: {}, actual: {}",
|
||||
self.socket.bus_name,
|
||||
reply.signature(),
|
||||
sig,
|
||||
reply.signature()
|
||||
);
|
||||
} else {
|
||||
let buf = unsafe { std::mem::take(msg_buf_data.get().deref_mut()) };
|
||||
|
|
@ -135,6 +135,39 @@ impl Incoming {
|
|||
}
|
||||
}
|
||||
}
|
||||
MSG_SIGNAL => {
|
||||
let (interface, member, path) =
|
||||
match (&headers.interface, &headers.member, &headers.path) {
|
||||
(Some(i), Some(m), Some(p)) => (i, m, p),
|
||||
_ => return Err(DbusError::MissingSignalHeaders),
|
||||
};
|
||||
let handlers = self.socket.signal_handlers.borrow_mut();
|
||||
if let Some(handler) = handlers.get(&(interface.deref(), member.deref())) {
|
||||
let handler = handler
|
||||
.conditional
|
||||
.get(path.deref())
|
||||
.or(handler.unconditional.as_ref());
|
||||
if let Some(handler) = handler {
|
||||
let sig = headers.signature.as_deref().unwrap_or("");
|
||||
if sig != handler.signature() {
|
||||
log::error!(
|
||||
"{}: Signal has an invalid signature: expected: {}, actual: {}",
|
||||
self.socket.bus_name,
|
||||
handler.signature(),
|
||||
sig,
|
||||
);
|
||||
} else {
|
||||
if let Err(e) = handler.handle(&mut parser) {
|
||||
log::error!(
|
||||
"{}: Could not handle signal: {}",
|
||||
self.socket.bus_name,
|
||||
ErrorFmt(e)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let msg_buf = msg_buf_data.into_inner();
|
||||
|
|
@ -174,7 +207,7 @@ impl Incoming {
|
|||
if e.0 != c::EAGAIN {
|
||||
return Err(DbusError::ReadError(e.into()));
|
||||
}
|
||||
let _ = self.socket.fd.readable().await;
|
||||
self.socket.fd.readable().await?;
|
||||
}
|
||||
if self.buf_start == self.buf_end {
|
||||
return Err(DbusError::Closed);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,11 @@ impl Outgoing {
|
|||
self.socket.kill();
|
||||
return;
|
||||
}
|
||||
let _ = self.socket.fd.writable().await;
|
||||
if let Err(e) = self.socket.fd.writable().await {
|
||||
log::error!("{}: Cannot wait for fd to become readable: {}", self.socket.bus_name, ErrorFmt(e));
|
||||
self.socket.kill();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@ use crate::dbus::property::Get;
|
|||
use crate::dbus::types::{ObjectPath, Signature, Variant};
|
||||
use crate::dbus::{
|
||||
AsyncProperty, AsyncReply, AsyncReplySlot, DbusError, DbusMessage, DbusSocket, DbusType,
|
||||
Formatter, Headers, Message, MethodCall, Parser, Property, Reply, ReplyHandler,
|
||||
Formatter, Headers, InterfaceSignalHandlers, Message, MethodCall, Parser, Property, Reply,
|
||||
ReplyHandler, Signal, SignalHandler, SignalHandlerApi, SignalHandlerData, BUS_DEST, BUS_PATH,
|
||||
HDR_DESTINATION, HDR_INTERFACE, HDR_MEMBER, HDR_PATH, HDR_SIGNATURE, HDR_UNIX_FDS,
|
||||
MSG_METHOD_CALL, NO_REPLY_EXPECTED,
|
||||
};
|
||||
use crate::{org, ErrorFmt};
|
||||
use std::cell::Cell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::Write;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::DerefMut;
|
||||
|
|
@ -116,6 +120,118 @@ impl DbusSocket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_signal<T, F>(
|
||||
self: &Rc<Self>,
|
||||
sender: Option<&str>,
|
||||
path: Option<&str>,
|
||||
handler: F,
|
||||
) -> Result<SignalHandler, DbusError>
|
||||
where
|
||||
T: Signal<'static>,
|
||||
F: for<'a> Fn(T::Generic<'a>) + 'static,
|
||||
{
|
||||
let mut rule = format!(
|
||||
"type='signal',interface='{}',member='{}'",
|
||||
T::INTERFACE,
|
||||
T::MEMBER
|
||||
);
|
||||
if let Some(sender) = sender {
|
||||
let _ = write!(rule, ",sender='{}'", sender);
|
||||
}
|
||||
if let Some(path) = path {
|
||||
let _ = write!(rule, ",path='{}'", path);
|
||||
}
|
||||
let shd: SignalHandlerData<T, _> = SignalHandlerData {
|
||||
path: path.map(|s| s.to_owned()),
|
||||
rule,
|
||||
handler,
|
||||
_phantom: Default::default(),
|
||||
};
|
||||
self.handle_signal_dyn(Rc::new(shd))
|
||||
}
|
||||
|
||||
fn handle_signal_dyn(
|
||||
self: &Rc<Self>,
|
||||
handler: Rc<dyn SignalHandlerApi>,
|
||||
) -> Result<SignalHandler, DbusError> {
|
||||
let mut sh = self.signal_handlers.borrow_mut();
|
||||
let entry = sh
|
||||
.entry((handler.interface(), handler.member()))
|
||||
.or_insert_with(|| InterfaceSignalHandlers {
|
||||
unconditional: Default::default(),
|
||||
conditional: Default::default(),
|
||||
});
|
||||
match handler.path() {
|
||||
Some(p) => match entry.conditional.entry(p.to_owned()) {
|
||||
Entry::Occupied(_) => return Err(DbusError::AlreadyHandled),
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(handler.clone());
|
||||
}
|
||||
},
|
||||
_ if entry.unconditional.is_some() => return Err(DbusError::AlreadyHandled),
|
||||
_ => entry.unconditional = Some(handler.clone()),
|
||||
}
|
||||
self.call(
|
||||
BUS_DEST,
|
||||
BUS_PATH,
|
||||
org::freedesktop::dbus::AddMatch {
|
||||
rule: handler.rule().into(),
|
||||
},
|
||||
{
|
||||
let slf = self.clone();
|
||||
move |res| {
|
||||
if let Err(e) = res {
|
||||
log::error!(
|
||||
"{}: Could not register a signal handler: {}",
|
||||
slf.bus_name,
|
||||
ErrorFmt(e)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
Ok(SignalHandler {
|
||||
socket: self.clone(),
|
||||
data: handler,
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn remove_signal_handler(self: &Rc<Self>, handler: &dyn SignalHandlerApi) {
|
||||
let mut sh = self.signal_handlers.borrow_mut();
|
||||
let mut entry = match sh.entry((handler.interface(), handler.member())) {
|
||||
Entry::Occupied(o) => o,
|
||||
Entry::Vacant(_) => return,
|
||||
};
|
||||
match handler.path() {
|
||||
Some(p) => {
|
||||
entry.get_mut().conditional.remove(p);
|
||||
}
|
||||
_ => entry.get_mut().unconditional = None,
|
||||
}
|
||||
if entry.get().unconditional.is_none() && entry.get().conditional.is_empty() {
|
||||
entry.remove();
|
||||
}
|
||||
self.call(
|
||||
BUS_DEST,
|
||||
BUS_PATH,
|
||||
org::freedesktop::dbus::RemoveMatch {
|
||||
rule: handler.rule().into(),
|
||||
},
|
||||
{
|
||||
let slf = self.clone();
|
||||
move |res| {
|
||||
if let Err(e) = res {
|
||||
log::error!(
|
||||
"{}: Could not unregister a signal handler: {}",
|
||||
slf.bus_name,
|
||||
ErrorFmt(e)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn send_call<'a, T: Message<'a>>(
|
||||
&self,
|
||||
path: &str,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use crate::dbus::{
|
|||
TY_INT16, TY_INT32, TY_INT64, TY_OBJECT_PATH, TY_SIGNATURE, TY_STRING, TY_UINT16, TY_UINT32,
|
||||
TY_UINT64, TY_UNIX_FD, TY_VARIANT,
|
||||
};
|
||||
use crate::utils::aligned::{AlignedF64, AlignedI64, AlignedU64};
|
||||
use std::borrow::Cow;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -139,7 +138,7 @@ unsafe impl<'a> DbusType<'a> for u32 {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a> DbusType<'a> for AlignedI64 {
|
||||
unsafe impl<'a> DbusType<'a> for i64 {
|
||||
const ALIGNMENT: usize = 8;
|
||||
const IS_POD: bool = true;
|
||||
type Generic<'b> = Self;
|
||||
|
|
@ -155,7 +154,7 @@ unsafe impl<'a> DbusType<'a> for AlignedI64 {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a> DbusType<'a> for AlignedU64 {
|
||||
unsafe impl<'a> DbusType<'a> for u64 {
|
||||
const ALIGNMENT: usize = 8;
|
||||
const IS_POD: bool = true;
|
||||
type Generic<'b> = Self;
|
||||
|
|
@ -171,7 +170,7 @@ unsafe impl<'a> DbusType<'a> for AlignedU64 {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a> DbusType<'a> for AlignedF64 {
|
||||
unsafe impl<'a> DbusType<'a> for f64 {
|
||||
const ALIGNMENT: usize = 8;
|
||||
const IS_POD: bool = true;
|
||||
type Generic<'b> = Self;
|
||||
|
|
@ -179,11 +178,11 @@ unsafe impl<'a> DbusType<'a> for AlignedF64 {
|
|||
signature!(TY_DOUBLE);
|
||||
|
||||
fn marshal(&self, fmt: &mut Formatter) {
|
||||
fmt.write_packed(self);
|
||||
fmt.write_packed(&self.to_bits());
|
||||
}
|
||||
|
||||
fn unmarshal(parser: &mut Parser<'a>) -> Result<Self, DbusError> {
|
||||
parser.read_pod()
|
||||
Ok(f64::from_bits(parser.read_pod()?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,9 +416,9 @@ pub enum Variant<'a> {
|
|||
U16(u16),
|
||||
I32(i32),
|
||||
U32(u32),
|
||||
I64(AlignedI64),
|
||||
U64(AlignedU64),
|
||||
F64(AlignedF64),
|
||||
I64(i64),
|
||||
U64(u64),
|
||||
F64(f64),
|
||||
String(Cow<'a, str>),
|
||||
ObjectPath(ObjectPath<'a>),
|
||||
Signature(Signature<'a>),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue