1
0
Fork 0
forked from wry/wry

autocommit 2022-03-02 14:24:07 CET

This commit is contained in:
Julian Orth 2022-03-02 14:24:07 +01:00
parent 0e9afcbfa5
commit aa0cb94143
30 changed files with 1059 additions and 123 deletions

View file

@ -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())),
}

View file

@ -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()?),

View file

@ -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(

View file

@ -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);

View file

@ -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;
}
}
}
}

View file

@ -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,

View file

@ -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>),