From 7da0d28318c97f1f3d629f13daad9ec824254709 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 15 Dec 2017 12:40:37 -0500 Subject: Keep track of required FDs per-expr --- cmdline.h | 4 ---- eval.c | 4 +++- expr.h | 5 +++++ opt.c | 13 +++++++++++++ parse.c | 25 ++++++++++++++----------- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/cmdline.h b/cmdline.h index 09500ce..e9731f9 100644 --- a/cmdline.h +++ b/cmdline.h @@ -98,10 +98,6 @@ struct cmdline { struct open_file *open_files; /** The number of open files owned by the command line. */ int nopen_files; - /** The number of files that may stay open between evaluations. */ - int persistent_fds; - /** The number of files that mau be opened during evaluations. */ - int ephemeral_fds; }; /** diff --git a/eval.c b/eval.c index d13b548..88616cc 100644 --- a/eval.c +++ b/eval.c @@ -1195,7 +1195,9 @@ static int infer_fdlimit(const struct cmdline *cmdline) { closedir(dir); } - ret -= nopen + cmdline->persistent_fds + cmdline->ephemeral_fds; + ret -= nopen; + ret -= cmdline->expr->persistent_fds; + ret -= cmdline->expr->ephemeral_fds; // bftw() needs at least 2 available fds if (ret < 2) { diff --git a/expr.h b/expr.h index 5581bf4..0cd08ce 100644 --- a/expr.h +++ b/expr.h @@ -192,6 +192,11 @@ struct expr { /** Optional string data for this expression. */ const char *sdata; + + /** The number of files this expression keeps open between evaluations. */ + int persistent_fds; + /** The number of files this expression opens during evaluation. */ + int ephemeral_fds; }; /** Singleton true expression instance. */ diff --git a/opt.c b/opt.c index 405f995..a7ebbe2 100644 --- a/opt.c +++ b/opt.c @@ -571,6 +571,19 @@ static struct expr *optimize_expr_recursive(struct opt_state *state, struct expr goto done; } + struct expr *lhs = expr->lhs; + struct expr *rhs = expr->rhs; + if (rhs) { + expr->persistent_fds = rhs->persistent_fds; + expr->ephemeral_fds = rhs->ephemeral_fds; + } + if (lhs) { + expr->persistent_fds += lhs->persistent_fds; + if (lhs->ephemeral_fds > expr->ephemeral_fds) { + expr->ephemeral_fds = lhs->ephemeral_fds; + } + } + if (expr->always_true) { set_facts_impossible(&state->facts_when_false); } diff --git a/parse.c b/parse.c index e173d10..0e4eaad 100644 --- a/parse.c +++ b/parse.c @@ -124,6 +124,8 @@ struct expr *new_expr(eval_fn *eval, size_t argc, char **argv) { expr->regex = NULL; expr->execbuf = NULL; expr->printf = NULL; + expr->persistent_fds = 0; + expr->ephemeral_fds = 0; return expr; } @@ -138,6 +140,8 @@ static struct expr *new_unary_expr(eval_fn *eval, struct expr *rhs, char **argv) } expr->rhs = rhs; + expr->persistent_fds = rhs->persistent_fds; + expr->ephemeral_fds = rhs->ephemeral_fds; return expr; } @@ -154,6 +158,12 @@ static struct expr *new_binary_expr(eval_fn *eval, struct expr *lhs, struct expr expr->lhs = lhs; expr->rhs = rhs; + expr->persistent_fds = lhs->persistent_fds + rhs->persistent_fds; + if (lhs->ephemeral_fds > rhs->ephemeral_fds) { + expr->ephemeral_fds = lhs->ephemeral_fds; + } else { + expr->ephemeral_fds = rhs->ephemeral_fds; + } return expr; } @@ -1073,9 +1083,7 @@ static struct expr *parse_empty(struct parser_state *state, int arg1, int arg2) expr->pure = false; } - if (cmdline->ephemeral_fds < 1) { - cmdline->ephemeral_fds = 1; - } + expr->ephemeral_fds = 1; return expr; } @@ -1105,17 +1113,14 @@ static struct expr *parse_exec(struct parser_state *state, int flags, int arg2) expr->cost = 1000000.0; } - int ephemeral_fds = 2; + expr->ephemeral_fds = 2; if (execbuf->flags & BFS_EXEC_CHDIR) { if (execbuf->flags & BFS_EXEC_MULTI) { - ++cmdline->persistent_fds; + expr->persistent_fds = 1; } else { - ++ephemeral_fds; + ++expr->ephemeral_fds; } } - if (cmdline->ephemeral_fds < ephemeral_fds) { - cmdline->ephemeral_fds = ephemeral_fds; - } return expr; } @@ -3051,8 +3056,6 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { cmdline->expr = &expr_true; cmdline->open_files = NULL; cmdline->nopen_files = 0; - cmdline->persistent_fds = 0; - cmdline->ephemeral_fds = 0; cmdline->argv = malloc((argc + 1)*sizeof(*cmdline->argv)); if (!cmdline->argv) { -- cgit v1.2.3