diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2022-11-09 11:35:53 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2022-11-09 12:09:45 -0500 |
commit | fc63f1b33fb438e8f7690db9bd84e3c69fe86b51 (patch) | |
tree | 79ad74fee5a8f922a6b19714affdcdbc26a317c1 /src | |
parent | b41dca52762c5188638236ae81b9f4597bb29ac9 (diff) | |
download | bfs-fc63f1b33fb438e8f7690db9bd84e3c69fe86b51.tar.xz |
ctx: Flush the user/group caches when executing commands
This fixes (admittedly uncommon) commands like
$ bfs -nouser -exec add-missing-user.sh {} \;
Diffstat (limited to 'src')
-rw-r--r-- | src/ctx.c | 5 | ||||
-rw-r--r-- | src/pwcache.c | 46 | ||||
-rw-r--r-- | src/pwcache.h | 16 |
3 files changed, 43 insertions, 24 deletions
@@ -186,6 +186,11 @@ void bfs_ctx_flush(const struct bfs_ctx *ctx) { // We do not check errors here, but they will be caught at cleanup time // with ferror(). fflush(NULL); + + // Flush the user/group caches, in case the executed command edits the + // user/group tables + bfs_users_flush(ctx->users); + bfs_groups_flush(ctx->groups); } /** Flush a file and report any errors. */ diff --git a/src/pwcache.c b/src/pwcache.c index 7071f59..868ec8f 100644 --- a/src/pwcache.c +++ b/src/pwcache.c @@ -64,6 +64,16 @@ static void *bfs_getent(struct trie_leaf *leaf, bfs_getent_fn *fn, const void *k } } +/** Flush a single cache. */ +static void bfs_pwcache_flush(struct trie *trie) { + TRIE_FOR_EACH(trie, leaf) { + if (leaf->value != MISSING) { + free(leaf->value); + } + trie_remove(trie, leaf); + } +} + struct bfs_users { /** Initial buffer size for getpw*_r(). */ size_t bufsize; @@ -123,22 +133,16 @@ const struct passwd *bfs_getpwuid(struct bfs_users *users, uid_t uid) { return bfs_getent(leaf, bfs_getpwuid_impl, &uid, sizeof(struct passwd), users->bufsize); } +void bfs_users_flush(struct bfs_users *users) { + bfs_pwcache_flush(&users->by_name); + bfs_pwcache_flush(&users->by_uid); +} + void bfs_users_free(struct bfs_users *users) { if (users) { - TRIE_FOR_EACH(&users->by_uid, leaf) { - if (leaf->value != MISSING) { - free(leaf->value); - } - } + bfs_users_flush(users); trie_destroy(&users->by_uid); - - TRIE_FOR_EACH(&users->by_name, leaf) { - if (leaf->value != MISSING) { - free(leaf->value); - } - } trie_destroy(&users->by_name); - free(users); } } @@ -202,22 +206,16 @@ const struct group *bfs_getgrgid(struct bfs_groups *groups, gid_t gid) { return bfs_getent(leaf, bfs_getgrgid_impl, &gid, sizeof(struct group), groups->bufsize); } +void bfs_groups_flush(struct bfs_groups *groups) { + bfs_pwcache_flush(&groups->by_name); + bfs_pwcache_flush(&groups->by_gid); +} + void bfs_groups_free(struct bfs_groups *groups) { if (groups) { - TRIE_FOR_EACH(&groups->by_gid, leaf) { - if (leaf->value != MISSING) { - free(leaf->value); - } - } + bfs_groups_flush(groups); trie_destroy(&groups->by_gid); - - TRIE_FOR_EACH(&groups->by_name, leaf) { - if (leaf->value != MISSING) { - free(leaf->value); - } - } trie_destroy(&groups->by_name); - free(groups); } } diff --git a/src/pwcache.h b/src/pwcache.h index 6ae8bea..f1ca0bf 100644 --- a/src/pwcache.h +++ b/src/pwcache.h @@ -64,6 +64,14 @@ const struct passwd *bfs_getpwnam(struct bfs_users *users, const char *name); const struct passwd *bfs_getpwuid(struct bfs_users *users, uid_t uid); /** + * Flush a user cache. + * + * @param users + * The cache to flush. + */ +void bfs_users_flush(struct bfs_users *users); + +/** * Free a user cache. * * @param users @@ -111,6 +119,14 @@ const struct group *bfs_getgrnam(struct bfs_groups *groups, const char *name); const struct group *bfs_getgrgid(struct bfs_groups *groups, gid_t gid); /** + * Flush a group cache. + * + * @param groups + * The cache to flush. + */ +void bfs_groups_flush(struct bfs_groups *groups); + +/** * Free a group cache. * * @param groups |