summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmdline.h4
-rw-r--r--eval.c3
-rw-r--r--parse.c28
3 files changed, 26 insertions, 9 deletions
diff --git a/cmdline.h b/cmdline.h
index e9731f9..09500ce 100644
--- a/cmdline.h
+++ b/cmdline.h
@@ -98,6 +98,10 @@ 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 fe89225..1c9ae50 100644
--- a/eval.c
+++ b/eval.c
@@ -1191,8 +1191,7 @@ static int infer_fdlimit(const struct cmdline *cmdline) {
closedir(dir);
}
- // 1 extra fd needed by -empty
- ret -= nopen + 1;
+ ret -= nopen + cmdline->persistent_fds + cmdline->ephemeral_fds;
// bftw() needs at least 2 available fds
if (ret < 2) {
diff --git a/parse.c b/parse.c
index 9d533ab..9054af7 100644
--- a/parse.c
+++ b/parse.c
@@ -1064,13 +1064,19 @@ static struct expr *parse_empty(struct parser_state *state, int arg1, int arg2)
expr->cost = 2000.0;
expr->probability = 0.01;
- if (state->cmdline->optlevel < 4) {
+ struct cmdline *cmdline = state->cmdline;
+
+ if (cmdline->optlevel < 4) {
// Since -empty attempts to open and read directories, it may
// have side effects such as reporting permission errors, and
// thus shouldn't be re-ordered without aggressive optimizations
expr->pure = false;
}
+ if (cmdline->ephemeral_fds < 1) {
+ cmdline->ephemeral_fds = 1;
+ }
+
return expr;
}
@@ -1078,28 +1084,34 @@ static struct expr *parse_empty(struct parser_state *state, int arg1, int arg2)
* Parse -exec(dir)?/-ok(dir)?.
*/
static struct expr *parse_exec(struct parser_state *state, int flags, int arg2) {
- struct bfs_exec *execbuf = parse_bfs_exec(state->argv, flags, state->cmdline);
+ struct cmdline *cmdline = state->cmdline;
+
+ struct bfs_exec *execbuf = parse_bfs_exec(state->argv, flags, cmdline);
if (!execbuf) {
return NULL;
}
- if ((execbuf->flags & BFS_EXEC_CHDIR) && (execbuf->flags & BFS_EXEC_MULTI)) {
- ++state->cmdline->nopen_files;
- }
-
struct expr *expr = parse_action(state, eval_exec, execbuf->tmpl_argc + 2);
if (!expr) {
free_bfs_exec(execbuf);
return NULL;
}
+ expr->execbuf = execbuf;
+
if (execbuf->flags & BFS_EXEC_MULTI) {
expr_set_always_true(expr);
} else {
expr->cost = 1000000.0;
}
- expr->execbuf = execbuf;
+ if (execbuf->flags & BFS_EXEC_CHDIR) {
+ if (execbuf->flags & BFS_EXEC_MULTI) {
+ ++cmdline->persistent_fds;
+ } else if (cmdline->ephemeral_fds < 1) {
+ cmdline->ephemeral_fds = 1;
+ }
+ }
return expr;
}
@@ -3035,6 +3047,8 @@ 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) {