diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-03-09 19:33:49 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-03-09 19:38:23 +0100 |
commit | d42688ef21a695f8a30b0d899dafdc6ff1ee0973 (patch) | |
tree | 91eb6e11244ee7f84fb3cf93b34b0829df5c72ab /src/fsckd/fsckd.c | |
parent | f699ebe13098af20033c615fa07fb435649a91c4 (diff) |
fsckd: free client event source before we close its fd
Diffstat (limited to 'src/fsckd/fsckd.c')
-rw-r--r-- | src/fsckd/fsckd.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c index 36b890a7de..c4135a5089 100644 --- a/src/fsckd/fsckd.c +++ b/src/fsckd/fsckd.c @@ -64,6 +64,8 @@ typedef struct Client { size_t buflen; bool cancelled; + sd_event_source *event_source; + LIST_FIELDS(struct Client, clients); } Client; @@ -86,7 +88,10 @@ typedef struct Manager { bool cancel_requested; } Manager; +static void client_free(Client *c); static void manager_free(Manager *m); + +DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free); DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); static double compute_percent(int pass, size_t cur, size_t max) { @@ -137,6 +142,8 @@ static void client_free(Client *c) { if (c->manager) LIST_REMOVE(clients, c->manager->clients, c); + sd_event_source_unref(c->event_source); + safe_close(c->fd); free(c); } @@ -372,8 +379,8 @@ static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents, } static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + _cleanup_(client_freep) Client *c = NULL; Manager *m = userdata; - Client *client = NULL; int new_client_fd, r; assert(m); @@ -385,21 +392,28 @@ static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t r log_debug("New fsck client connected to fd: %d", new_client_fd); - client = new0(Client, 1); - if (!client) - return log_oom(); - client->fd = new_client_fd; - client->manager = m; - LIST_PREPEND(clients, m->clients, client); - r = sd_event_add_io(m->event, NULL, client->fd, EPOLLIN, client_progress_handler, client); + c = new0(Client, 1); + if (!c) { + safe_close(new_client_fd); + log_oom(); + return 0; + } + + c->fd = new_client_fd; + r = sd_event_add_io(m->event, &c->event_source, c->fd, EPOLLIN, client_progress_handler, c); if (r < 0) { - client_free(client); - return r; + log_oom(); + return 0; } + + LIST_PREPEND(clients, m->clients, c); + c->manager = m; + /* only request the client to cancel now in case the request is dropped by the client (chance to recancel) */ if (m->cancel_requested) - client_request_cancel(client); + client_request_cancel(c); + c = NULL; return 0; } |