diff --git a/man/rules/meson.build b/man/rules/meson.build
index b3011c5f04..33301d4b6d 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -289,6 +289,7 @@ manpages = [
'sd_bus_release_name_async',
'sd_bus_request_name_async'],
''],
+ ['sd_bus_set_close_on_exit', '3', ['sd_bus_get_close_on_exit'], ''],
['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
['sd_bus_set_description',
'3',
diff --git a/man/sd-bus.xml b/man/sd-bus.xml
index bf2f37a86d..1df988cf7a 100644
--- a/man/sd-bus.xml
+++ b/man/sd-bus.xml
@@ -84,6 +84,7 @@
sd_bus_set_description3,
sd_bus_set_sender3,
sd_bus_set_watch_bind3
+sd_bus_set_close_on_exit3
sd_bus_slot_set_description3,
sd_bus_slot_set_destroy_callback3,
sd_bus_slot_set_floating3,
diff --git a/man/sd_bus_set_close_on_exit.xml b/man/sd_bus_set_close_on_exit.xml
new file mode 100644
index 0000000000..dc4f6a3e15
--- /dev/null
+++ b/man/sd_bus_set_close_on_exit.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+ sd_bus_set_close_on_exit
+ systemd
+
+
+
+ sd_bus_set_close_on_exit
+ 3
+
+
+
+ sd_bus_set_close_on_exit
+ sd_bus_get_close_on_exit
+
+ Control whether to close the bus connection during the event loop exit phase
+
+
+
+
+ #include <systemd/sd-bus.h>
+
+
+ int sd_bus_set_close_on_exit
+ sd_bus *bus
+ int b
+
+
+
+ int sd_bus_get_close_on_exit
+ sd_bus *bus
+
+
+
+
+
+
+ Description
+
+ sd_bus_set_close_on_exit() may be used to enable or disable whether the bus connection
+ is automatically flushed (as in
+ sd_bus_flush3) and closed (as in
+ sd_bus_close3) during the exit
+ phase of the event loop. This logic only applies to bus connections that are attached to an
+ sd-event3 event loop, see
+ sd_bus_attach_event3. By default
+ this mechanism is enabled and makes sure that any pending messages that have not been written to the bus connection
+ are written out when the event loop is shutting down. In some cases this behaviour is not desirable, for example
+ when the bus connection shall remain usable until after the event loop exited. If b is
+ true, the feature is enabled (which is the default), otherwise disabled.
+
+ sd_bus_get_close_on_exit() may be used to query the current setting of this feature. It
+ returns zero when the feature is disabled, and positive if enabled.
+
+
+
+ Return Value
+
+ On success, sd_bus_set_close_on_exit() returns 0 or a positive integer. On failure, it returns a negative errno-style
+ error code.
+
+ sd_bus_get_close_on_exit() returns 0 if the feature is currently turned off or a
+ positive integer if it is on. On failure, it returns a negative errno-style error code.
+
+
+
+ Errors
+
+ Returned errors may indicate the following problems:
+
+
+
+ -ECHILD
+
+ The bus connection has been created in a different process.
+
+
+
+
+
+
+
+ See Also
+
+
+ systemd1,
+ sd-bus3,
+ sd_bus_flush3,
+ sd_bus_attach_event3,
+ sd-event3,
+ sd_event_add_exit3
+
+
+
+
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 1f2238ca37..6a64b929dd 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -579,6 +579,9 @@ global:
sd_bus_error_move;
+ sd_bus_set_close_on_exit;
+ sd_bus_get_close_on_exit;
+
sd_device_ref;
sd_device_unref;
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 55f2bc36fb..4bc945d9ee 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -211,6 +211,7 @@ struct sd_bus {
bool accept_fd:1;
bool attach_timestamp:1;
bool connected_signal:1;
+ bool close_on_exit:1;
int use_memfd;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index bc7d00c3d0..f086d13898 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -232,18 +232,22 @@ _public_ int sd_bus_new(sd_bus **ret) {
assert_return(ret, -EINVAL);
- b = new0(sd_bus, 1);
+ b = new(sd_bus, 1);
if (!b)
return -ENOMEM;
- b->n_ref = REFCNT_INIT;
- b->input_fd = b->output_fd = -1;
- b->inotify_fd = -1;
- b->message_version = 1;
- b->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
- b->accept_fd = true;
- b->original_pid = getpid_cached();
- b->n_groups = (size_t) -1;
+ *b = (sd_bus) {
+ .n_ref = REFCNT_INIT,
+ .input_fd = -1,
+ .output_fd = -1,
+ .inotify_fd = -1,
+ .message_version = 1,
+ .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
+ .accept_fd = true,
+ .original_pid = getpid_cached(),
+ .n_groups = (size_t) -1,
+ .close_on_exit = true,
+ };
assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
@@ -3409,8 +3413,10 @@ static int quit_callback(sd_event_source *event, void *userdata) {
assert(event);
- sd_bus_flush(bus);
- sd_bus_close(bus);
+ if (bus->close_on_exit) {
+ sd_bus_flush(bus);
+ sd_bus_close(bus);
+ }
return 1;
}
@@ -4135,3 +4141,18 @@ _public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
*ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
return 0;
}
+
+_public_ int sd_bus_set_close_on_exit(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+ bus->close_on_exit = b;
+ return 0;
+}
+
+_public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus = bus_resolve(bus), -ENOPKG);
+
+ return bus->close_on_exit;
+}
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 9c4bbed9dc..220ddb99ec 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -154,6 +154,8 @@ 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_set_exit_on_disconnect(sd_bus *bus, int b);
int sd_bus_get_exit_on_disconnect(sd_bus *bus);
+int sd_bus_set_close_on_exit(sd_bus *bus, int b);
+int sd_bus_get_close_on_exit(sd_bus *bus);
int sd_bus_set_watch_bind(sd_bus *bus, int b);
int sd_bus_get_watch_bind(sd_bus *bus);
int sd_bus_set_connected_signal(sd_bus *bus, int b);