diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2015-11-28 11:26:51 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2015-11-28 11:26:51 -0500 |
commit | f81be72020a886b5eca21bc1d8a5b0d62b9954d9 (patch) | |
tree | 0857734c416768778dd27b7b87b12c417594ea62 | |
parent | 85bb6db3e14a38a2b9c6085e806873aeeacc9b95 (diff) | |
download | bfs-f81be72020a886b5eca21bc1d8a5b0d62b9954d9.tar.xz |
Implement -executable, -readable, and -writable.
-rw-r--r-- | bfs.c | 14 | ||||
-rwxr-xr-x | tests.sh | 27 |
2 files changed, 40 insertions, 1 deletions
@@ -284,6 +284,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. */ static bool eval_delete(const expression *expr, eval_state *state) { @@ -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; @@ -18,6 +18,16 @@ function basic_structure() { touchp "$1/l/foo/bar/baz" } +# Creates a file+directory structure with various permissions for tests +function perms_structure() { + install -Dm444 /dev/null "$1/r" + install -Dm222 /dev/null "$1/w" + install -Dm644 /dev/null "$1/rw" + install -Dm555 /dev/null "$1/rx" + install -Dm311 /dev/null "$1/wx" + install -Dm755 /dev/null "$1/rwx" +} + # Checks for any (order-independent) differences between bfs and find function find_diff() { diff -u <(./bfs "$@" | sort) <(find "$@" | sort) @@ -80,7 +90,22 @@ function test_0011() { find_diff "$1" -path "$1/*f*" } -for i in {1..11}; do +function test_0012() { + perms_structure "$1" + find_diff "$1" -executable +} + +function test_0013() { + perms_structure "$1" + find_diff "$1" -readable +} + +function test_0014() { + perms_structure "$1" + find_diff "$1" -writable +} + +for i in {1..14}; do dir="$(mktemp -d "${TMPDIR:-/tmp}"/bfs.XXXXXXXXXX)" test="test_$(printf '%04d' $i)" "$test" "$dir" |