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