From ab93297cd07361d1e7ce666740e09689a34c65b9 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 24 Jan 2018 09:45:48 -0500 Subject: [PATCH] Add fd close support to sd_event_source It is often the case that a file descriptor and its corresponding IO sd_event_source share a life span. When this is the case, developers will have to unref the event source and close the file descriptor. Instead, we can just have the event source take ownership of the file descriptor and close it when the event source is freed. This is especially useful when combined with cleanup attributes and sd_event_source_unrefp(). This patch adds two new public functions: sd_event_source_get_io_fd_own() sd_event_source_set_io_fd_own() --- src/libsystemd/libsystemd.sym | 2 ++ src/libsystemd/sd-event/sd-event.c | 20 ++++++++++++++++++++ src/systemd/sd-event.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 5a07344..00aeefb 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -546,4 +546,6 @@ global: sd_bus_set_sender; sd_bus_get_sender; sd_bus_message_set_sender; + sd_event_source_get_io_fd_own; + sd_event_source_set_io_fd_own; } LIBSYSTEMD_236; diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index be78a36..cb9b3a4 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -122,6 +122,7 @@ struct sd_event_source { uint32_t events; uint32_t revents; bool registered:1; + bool owned:1; } io; struct { sd_event_time_handler_t callback; @@ -889,6 +890,10 @@ static void source_free(sd_event_source *s) { assert(s); source_disconnect(s); + + if (s->type == SOURCE_IO && s->io.owned) + safe_close(s->io.fd); + free(s->description); free(s); } @@ -1494,6 +1499,21 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { return 0; } +_public_ int sd_event_source_get_io_fd_own(sd_event_source *s) { + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + + return s->io.owned; +} + +_public_ int sd_event_source_set_io_fd_own(sd_event_source *s, int own) { + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + + s->io.owned = own; + return 0; +} + _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { assert_return(s, -EINVAL); assert_return(events, -EINVAL); diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h index 676d870..ec4b7bc 100644 --- a/src/systemd/sd-event.h +++ b/src/systemd/sd-event.h @@ -127,6 +127,8 @@ int sd_event_source_get_enabled(sd_event_source *s, int *enabled); int sd_event_source_set_enabled(sd_event_source *s, int enabled); int sd_event_source_get_io_fd(sd_event_source *s); int sd_event_source_set_io_fd(sd_event_source *s, int fd); +int sd_event_source_get_io_fd_own(sd_event_source *s); +int sd_event_source_set_io_fd_own(sd_event_source *s, int own); int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events); int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); -- 2.7.4