mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-28 11:55:23 +03:00
sd-bus: optionally, exit process or event loop on disconnect
Old libdbus has a feature that the process is terminated whenever the the bus connection receives a disconnect. This is pretty useful on desktop apps (where a disconnect indicates session termination), as well as on command line apps (where we really shouldn't stay hanging in most cases if dbus daemon goes down). Add a similar feature to sd-bus, but make it opt-in rather than opt-out, like it is on libdbus. Also, if the bus is attached to an event loop just exit the event loop rather than the the whole process.
This commit is contained in:
parent
2c5f295823
commit
fbb4603d48
@ -507,4 +507,6 @@ global:
|
|||||||
sd_bus_track_get_recursive;
|
sd_bus_track_get_recursive;
|
||||||
sd_bus_track_count_name;
|
sd_bus_track_count_name;
|
||||||
sd_bus_track_count_sender;
|
sd_bus_track_count_sender;
|
||||||
|
sd_bus_set_exit_on_disconnect;
|
||||||
|
sd_bus_get_exit_on_disconnect;
|
||||||
} LIBSYSTEMD_231;
|
} LIBSYSTEMD_231;
|
||||||
|
@ -209,6 +209,9 @@ struct sd_bus {
|
|||||||
bool is_system:1;
|
bool is_system:1;
|
||||||
bool is_user:1;
|
bool is_user:1;
|
||||||
bool allow_interactive_authorization:1;
|
bool allow_interactive_authorization:1;
|
||||||
|
bool exit_on_disconnect:1;
|
||||||
|
bool exited:1;
|
||||||
|
bool exit_triggered:1;
|
||||||
|
|
||||||
int use_memfd;
|
int use_memfd;
|
||||||
|
|
||||||
|
@ -2641,6 +2641,31 @@ null_message:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bus_exit_now(sd_bus *bus) {
|
||||||
|
assert(bus);
|
||||||
|
|
||||||
|
/* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
|
||||||
|
* sd_event_exit(), otherwise invokes libc exit(). */
|
||||||
|
|
||||||
|
if (bus->exited) /* did we already exit? */
|
||||||
|
return 0;
|
||||||
|
if (!bus->exit_triggered) /* was the exit condition triggered? */
|
||||||
|
return 0;
|
||||||
|
if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bus->exited = true; /* never exit more than once */
|
||||||
|
|
||||||
|
log_debug("Bus connection disconnected, exiting.");
|
||||||
|
|
||||||
|
if (bus->event)
|
||||||
|
return sd_event_exit(bus->event, EXIT_FAILURE);
|
||||||
|
else
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
assert_not_reached("exit() didn't exit?");
|
||||||
|
}
|
||||||
|
|
||||||
static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
|
static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
|
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||||
@ -2742,6 +2767,10 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
/* Nothing else to do, exit now, if the condition holds */
|
||||||
|
bus->exit_triggered = true;
|
||||||
|
(void) bus_exit_now(bus);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
*ret = m;
|
*ret = m;
|
||||||
m = NULL;
|
m = NULL;
|
||||||
@ -3804,3 +3833,21 @@ _public_ void sd_bus_default_flush_close(void) {
|
|||||||
flush_close(default_user_bus);
|
flush_close(default_user_bus);
|
||||||
flush_close(default_system_bus);
|
flush_close(default_system_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) {
|
||||||
|
assert_return(bus, -EINVAL);
|
||||||
|
|
||||||
|
/* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already
|
||||||
|
* disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never
|
||||||
|
* from the client side. */
|
||||||
|
bus->exit_on_disconnect = b;
|
||||||
|
|
||||||
|
/* If the exit condition was triggered already, exit immediately. */
|
||||||
|
return bus_exit_now(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) {
|
||||||
|
assert_return(bus, -EINVAL);
|
||||||
|
|
||||||
|
return bus->exit_on_disconnect;
|
||||||
|
}
|
||||||
|
@ -147,6 +147,8 @@ int sd_bus_can_send(sd_bus *bus, char type);
|
|||||||
int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *creds_mask);
|
int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *creds_mask);
|
||||||
int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b);
|
int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b);
|
||||||
int sd_bus_get_allow_interactive_authorization(sd_bus *bus);
|
int sd_bus_get_allow_interactive_authorization(sd_bus *bus);
|
||||||
|
int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b);
|
||||||
|
int sd_bus_get_exit_on_disconnect(sd_bus *bus);
|
||||||
|
|
||||||
int sd_bus_start(sd_bus *ret);
|
int sd_bus_start(sd_bus *ret);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user