diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-10-17 11:55:31 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-10-17 12:33:39 -0400 |
commit | dd1c8c2f08d232d5745dc1f5fe483ec4072fe454 (patch) | |
tree | e4b1b5720d7df0bc3ca9aa0fb9fdc0d50636d019 | |
parent | 68949cf1b9cb5336ea06ad7f87db8e28b620f2ac (diff) | |
download | bfs-dd1c8c2f08d232d5745dc1f5fe483ec4072fe454.tar.xz |
parse: Set BFTW_WHITEOUTS when parsing -type w
-rw-r--r-- | src/parse.c | 3 | ||||
-rw-r--r-- | tests/bsd/type_w.out | 38 | ||||
-rw-r--r-- | tests/bsd/type_w.sh | 64 |
3 files changed, 105 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c index 976f7cb..fafd787 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2514,6 +2514,8 @@ static struct bfs_expr *parse_status(struct parser_state *state, int arg1, int a * Parse -x?type [bcdpflsD]. */ static struct bfs_expr *parse_type(struct parser_state *state, int x, int arg2) { + struct bfs_ctx *ctx = state->ctx; + bfs_eval_fn *eval = x ? eval_xtype : eval_type; struct bfs_expr *expr = parse_unary_test(state, eval); if (!expr) { @@ -2551,6 +2553,7 @@ static struct bfs_expr *parse_type(struct parser_state *state, int x, int arg2) break; case 'w': expr->num |= 1 << BFS_WHT; + ctx->flags |= BFTW_WHITEOUTS; break; case '\0': diff --git a/tests/bsd/type_w.out b/tests/bsd/type_w.out new file mode 100644 index 0000000..d383f69 --- /dev/null +++ b/tests/bsd/type_w.out @@ -0,0 +1,38 @@ +1: -rw-r--r-- scratch/mnt/lower/bar +1: -rw-r--r-- scratch/mnt/lower/baz +1: -rw-r--r-- scratch/mnt/lower/foo +1: -rw-r--r-- scratch/mnt/upper/baz/qux +1: -rw-r--r-- scratch/mnt/upper/foo +1: drwxr-xr-x scratch/mnt +1: drwxr-xr-x scratch/mnt/lower +1: drwxr-xr-x scratch/mnt/upper +1: drwxr-xr-x scratch/mnt/upper/baz +2: w--------- scratch/mnt/upper/bar +3: -rw-r--r-- scratch/mnt/lower/bar +3: -rw-r--r-- scratch/mnt/lower/baz +3: -rw-r--r-- scratch/mnt/lower/foo +3: -rw-r--r-- scratch/mnt/upper/baz/qux +3: -rw-r--r-- scratch/mnt/upper/foo +3: drwxr-xr-x scratch/mnt +3: drwxr-xr-x scratch/mnt/lower +3: drwxr-xr-x scratch/mnt/upper +3: drwxr-xr-x scratch/mnt/upper/baz +3: w--------- scratch/mnt/upper/bar +4: -rw-r--r-- scratch/mnt/lower/bar +4: -rw-r--r-- scratch/mnt/lower/baz +4: -rw-r--r-- scratch/mnt/lower/foo +4: -rw-r--r-- scratch/mnt/upper/baz/qux +4: drwxr-xr-x scratch/mnt +4: drwxr-xr-x scratch/mnt/lower +4: drwxr-xr-x scratch/mnt/upper +4: drwxr-xr-x scratch/mnt/upper/baz +5: w--------- scratch/mnt/upper/bar +6: -rw-r--r-- scratch/mnt/lower/bar +6: -rw-r--r-- scratch/mnt/lower/baz +6: -rw-r--r-- scratch/mnt/lower/foo +6: -rw-r--r-- scratch/mnt/upper/baz/qux +6: drwxr-xr-x scratch/mnt +6: drwxr-xr-x scratch/mnt/lower +6: drwxr-xr-x scratch/mnt/upper +6: drwxr-xr-x scratch/mnt/upper/baz +6: w--------- scratch/mnt/upper/bar diff --git a/tests/bsd/type_w.sh b/tests/bsd/type_w.sh new file mode 100644 index 0000000..d0cb58c --- /dev/null +++ b/tests/bsd/type_w.sh @@ -0,0 +1,64 @@ +# Only ffs supports whiteouts on FreeBSD +command -v mdconfig &>/dev/null || skip +command -v newfs &>/dev/null || skip + +cleanup=() +do_cleanup() { + # Run cleanup hooks in reverse order + while ((${#cleanup[@]} > 0)); do + cmd="${cleanup[-1]}" + unset 'cleanup[-1]' + eval "bfs_sudo $cmd" + done +} +trap do_cleanup EXIT + +clean_scratch + +# Create a ramdisk +truncate -s1M scratch/img +md=$(bfs_sudo mdconfig scratch/img) || skip +cleanup+=("mdconfig -du $md") + +# Make an ffs filesystem +bfs_sudo newfs -n "/dev/$md" >&2 || skip +mkdir scratch/mnt + +# Mount it +bfs_sudo mount "/dev/$md" scratch/mnt || skip +cleanup+=("umount scratch/mnt") + +# Make it owned by us +bfs_sudo chown "$(id -u):$(id -g)" scratch/mnt +"$XTOUCH" -p scratch/mnt/{lower/{foo,bar,baz},upper/{bar,baz/qux}} + +# Mount a union filesystem within it +bfs_sudo mount -t unionfs -o below scratch/mnt/{lower,upper} +cleanup+=("umount scratch/mnt/upper") + +# Create a whiteout +rm scratch/mnt/upper/bar + +# FreeBSD find doesn't have -printf, so munge -ls output +munge_ls() { + sed -En 's|.*([-drwx]{10}).*(scratch/.*)|'"$1"': \1 \2|p' +} + +# Do a few tests in one +{ + # Normally, we shouldn't see the whiteouts + invoke_bfs scratch/mnt -ls | munge_ls 1 + # -type w adds whiteouts to the output + invoke_bfs scratch/mnt -type w -ls | munge_ls 2 + # So this is not the same as test 1 + invoke_bfs scratch/mnt \( -type w -or -not -type w \) -ls | munge_ls 3 + # Unmount the unionfs + bfs_sudo umount scratch/mnt/upper + unset 'cleanup[-1]' + # Now repeat the same tests + invoke_bfs scratch/mnt -ls | munge_ls 4 + invoke_bfs scratch/mnt -type w -ls | munge_ls 5 + invoke_bfs scratch/mnt \( -type w -or -not -type w \) -ls | munge_ls 6 +} >"$OUT" +sort_output +diff_output |