summaryrefslogtreecommitdiffstats
path: root/src/ctx.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2022-11-09 11:14:12 -0500
committerTavian Barnes <tavianator@tavianator.com>2022-11-09 12:08:20 -0500
commitb41dca52762c5188638236ae81b9f4597bb29ac9 (patch)
tree4d503f6dcee1b1ed15ef61df3c8ccb9b92533546 /src/ctx.c
parentdd6808539013061a3113e45c7267430e56749f2c (diff)
downloadbfs-b41dca52762c5188638236ae81b9f4597bb29ac9.tar.xz
pwcache: Fill the user/group caches lazily
Iterating all the users/groups can be expensive, especially with NSS. Android has so many that it doesn't even return them all from get{pw,gr}ent() for performance reasons, leading to incorrect behaviour of -user/-group/etc.
Diffstat (limited to 'src/ctx.c')
-rw-r--r--src/ctx.c50
1 files changed, 15 insertions, 35 deletions
diff --git a/src/ctx.c b/src/ctx.c
index b2f7d56..8d80691 100644
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -84,9 +84,7 @@ struct bfs_ctx *bfs_ctx_new(void) {
ctx->cerr = NULL;
ctx->users = NULL;
- ctx->users_error = 0;
ctx->groups = NULL;
- ctx->groups_error = 0;
ctx->mtab = NULL;
ctx->mtab_error = 0;
@@ -95,45 +93,27 @@ struct bfs_ctx *bfs_ctx_new(void) {
ctx->nfiles = 0;
struct rlimit rl;
- if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
- ctx->nofile_soft = rl.rlim_cur;
- ctx->nofile_hard = rl.rlim_max;
- } else {
- ctx->nofile_soft = 1024;
- ctx->nofile_hard = RLIM_INFINITY;
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) {
+ goto fail;
}
+ ctx->nofile_soft = rl.rlim_cur;
+ ctx->nofile_hard = rl.rlim_max;
- return ctx;
-}
-
-const struct bfs_users *bfs_ctx_users(const struct bfs_ctx *ctx) {
- struct bfs_ctx *mut = (struct bfs_ctx *)ctx;
-
- if (mut->users_error) {
- errno = mut->users_error;
- } else if (!mut->users) {
- mut->users = bfs_users_parse();
- if (!mut->users) {
- mut->users_error = errno;
- }
+ ctx->users = bfs_users_new();
+ if (!ctx->users) {
+ goto fail;
}
- return mut->users;
-}
-
-const struct bfs_groups *bfs_ctx_groups(const struct bfs_ctx *ctx) {
- struct bfs_ctx *mut = (struct bfs_ctx *)ctx;
-
- if (mut->groups_error) {
- errno = mut->groups_error;
- } else if (!mut->groups) {
- mut->groups = bfs_groups_parse();
- if (!mut->groups) {
- mut->groups_error = errno;
- }
+ ctx->groups = bfs_groups_new();
+ if (!ctx->groups) {
+ goto fail;
}
- return mut->groups;
+ return ctx;
+
+fail:
+ bfs_ctx_free(ctx);
+ return NULL;
}
const struct bfs_mtab *bfs_ctx_mtab(const struct bfs_ctx *ctx) {