mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
man: enchance sd_bus_set_watch_bind() example to handle one more failure
In case the D-Bus policy is not set up correctly the example just
loops forever. Check the return of sd_bus_request_name_async() in
a callback and exit if the error is not temporary.
Follow-up for 34bbda18a5
This commit is contained in:
parent
d0aef638ac
commit
e07e7017bb
@ -5,7 +5,8 @@
|
||||
* Compile with 'cc sd_bus_service_reconnect.c $(pkg-config --libs --cflags libsystemd)'
|
||||
*
|
||||
* To allow the program to take ownership of the name 'org.freedesktop.ReconnectExample',
|
||||
* add the following as /etc/dbus-1/system.d/org.freedesktop.ReconnectExample.conf:
|
||||
* add the following as /etc/dbus-1/system.d/org.freedesktop.ReconnectExample.conf
|
||||
* and then reload the broker with 'systemctl reload dbus':
|
||||
|
||||
<?xml version="1.0"?> <!--*-nxml-*-->
|
||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
@ -92,6 +93,23 @@ static int on_disconnect(sd_bus_message *message, void *userdata, sd_bus_error *
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure the event loop exits with a clear error if acquiring the well-known service name fails */
|
||||
static int request_name_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
|
||||
if (!sd_bus_message_is_method_error(m, NULL))
|
||||
return 1;
|
||||
|
||||
const sd_bus_error *error = sd_bus_message_get_error(m);
|
||||
|
||||
if (sd_bus_error_has_names(error, SD_BUS_ERROR_TIMEOUT, SD_BUS_ERROR_NO_REPLY))
|
||||
return 1; /* The bus is not available, try again later */
|
||||
|
||||
printf("Failed to request name: %s\n", error->message);
|
||||
object *o = userdata;
|
||||
check(sd_event_exit(*o->event, -sd_bus_error_get_errno(error)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int setup(object *o) {
|
||||
/* If we are reconnecting, then the bus object needs to be closed, detached from
|
||||
* the event loop and recreated.
|
||||
@ -119,7 +137,6 @@ static int setup(object *o) {
|
||||
check(sd_bus_set_bus_client(*o->bus, 1));
|
||||
check(sd_bus_negotiate_creds(*o->bus, 1, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS));
|
||||
check(sd_bus_set_watch_bind(*o->bus, 1));
|
||||
check(sd_bus_set_connected_signal(*o->bus, 1));
|
||||
check(sd_bus_start(*o->bus));
|
||||
|
||||
/* Publish an interface on the bus, specifying our well-known object access
|
||||
@ -135,15 +152,16 @@ static int setup(object *o) {
|
||||
o));
|
||||
/* By default the service is only assigned an ephemeral name. Also add a well-known
|
||||
* one, so that clients know whom to call. This needs to be asynchronous, as
|
||||
* D-Bus might not be yet available.
|
||||
* D-Bus might not be yet available. The callback will check whether the error is
|
||||
* expected or not, in case it fails.
|
||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
|
||||
*/
|
||||
check(sd_bus_request_name_async(*o->bus,
|
||||
NULL,
|
||||
"org.freedesktop.ReconnectExample",
|
||||
0,
|
||||
NULL,
|
||||
NULL));
|
||||
request_name_callback,
|
||||
o));
|
||||
/* When D-Bus is disconnected this callback will be invoked, which will
|
||||
* set up the connection again. This needs to be asynchronous, as D-Bus might not
|
||||
* yet be available.
|
||||
|
Loading…
Reference in New Issue
Block a user