From f81be72020a886b5eca21bc1d8a5b0d62b9954d9 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 28 Nov 2015 11:26:51 -0500 Subject: Implement -executable, -readable, and -writable. --- bfs.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'bfs.c') diff --git a/bfs.c b/bfs.c index 4ec9026..d9d1f7a 100644 --- a/bfs.c +++ b/bfs.c @@ -283,6 +283,14 @@ static const char *skip_paths(parser_state *state) { } } +/** + * -executable, -readable, -writable action. + */ +static bool eval_access(const expression *expr, eval_state *state) { + struct BFTW *ftwbuf = state->ftwbuf; + return faccessat(ftwbuf->at_fd, ftwbuf->at_path, expr->idata, AT_SYMLINK_NOFOLLOW) == 0; +} + /** * -delete action. */ @@ -567,6 +575,8 @@ static expression *parse_literal(parser_state *state) { } else if (strcmp(arg, "-d") == 0 || strcmp(arg, "-depth") == 0) { state->cl->flags |= BFTW_DEPTH; return new_option(state, arg); + } else if (strcmp(arg, "-executable") == 0) { + return new_test_idata(state, eval_access, X_OK); } else if (strcmp(arg, "-false") == 0) { return &expr_false; } else if (strcmp(arg, "-hidden") == 0) { @@ -589,6 +599,8 @@ static expression *parse_literal(parser_state *state) { return new_action(state, eval_prune); } else if (strcmp(arg, "-quit") == 0) { return new_action(state, eval_quit); + } else if (strcmp(arg, "-readable") == 0) { + return new_test_idata(state, eval_access, R_OK); } else if (strcmp(arg, "-true") == 0) { return &expr_true; } else if (strcmp(arg, "-type") == 0) { @@ -599,6 +611,8 @@ static expression *parse_literal(parser_state *state) { } else if (strcmp(arg, "-nowarn") == 0) { state->warn = false; return new_positional_option(state); + } else if (strcmp(arg, "-writable") == 0) { + return new_test_idata(state, eval_access, W_OK); } else { fprintf(stderr, "Unknown argument '%s'.\n", arg); return NULL; -- cgit v1.2.3