From 414a49d73338357c873a73851011d0b338269e49 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 19 Mar 2023 09:29:03 +0100 Subject: [PATCH] Fix regression in .conf reload when changing runlevel When the inotify callback is called for a file that has been removed, the call to realpath() obviously fails (ENOENT). This fix only takes the regular case into account, files removed from a symlinked enabled directory is not handled -- needs more work for that. Regression introduced in 0a94f3f, PR #347, issue #346. Signed-off-by: Joachim Wiberg --- src/conf.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/conf.c b/src/conf.c index 011eaf69..88488753 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1127,22 +1127,28 @@ static void drop_changes(void) drop_change(node); } -static int do_change(char *dir, char *name, uint32_t mask) +static int conf_change_act(char *dir, char *name, uint32_t mask) { char fn[strlen(dir) + strlen(name) + 2]; - char *rp; struct conf_change *node; + char *rp = NULL; paste(fn, sizeof(fn), dir, name); dbg("path: %s mask: %08x", fn, mask); + /* Handle disabling/removal of service */ rp = realpath(fn, NULL); - if (!rp) - return 0; + if (!rp) { + if (errno != ENOENT) + goto fail; + rp = strdup(fn); + if (!rp) + goto fail; + } node = conf_find(rp); if (node) { - dbg("Event already registered for %s ...", name); + dbg("event already registered for %s ...", name); free(rp); return 0; } @@ -1150,21 +1156,16 @@ static int do_change(char *dir, char *name, uint32_t mask) node = malloc(sizeof(*node)); if (!node) { free(rp); - return 1; + goto fail; } - node->name = strdup(rp); - if (!node->name) { - free(node); - free(rp); - return 1; - } - - dbg("Event registered for %s, mask 0x%x", rp, mask); + node->name = rp; TAILQ_INSERT_HEAD(&conf_change_list, node, link); - - free(rp); + dbg("event registered for %s, mask 0x%x", rp, mask); return 0; +fail: + warn("failed registering %s event", fn); + return 1; } int conf_any_change(void)