summaryrefslogtreecommitdiff
path: root/tests/find/files0-from.sh
blob: b930a9998fe20f9791d59496738947602342f7aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/sh
# Exercise -files0-from option.

# Copyright (C) 2021 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

. "${srcdir=.}/tests/init.sh"; fu_path_prepend_
print_ver_ find

# Option -files0-from requires a file name argument.
returns_ 1 find -files0-from > out 2> err \
  && grep 'missing argument.*files0' err \
  || { grep . out err; fail=1; }

# Option -files0-from must not be combined with passing starting points on
# the command line.
returns_ 1 find OFFENDING -files0-from FILE > out 2> err \
  && grep 'extra operand .*OFFENDING' err \
  && grep 'file operands cannot be combined with -files0-from' err \
  || { grep . out err; fail=1; }

# Process "." as default when starting points neither passed via -files0-from
# nor on the command line.
printf "%s\n" '.' > exp || framework_failure_
find -maxdepth 0 > out 2> err || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1

# Option -files0-from with argument "-" (=stdin) must not be combined with
# the -ok action: getting the user confirmation would mess with stdin.
returns_ 1 find -files0-from - -ok echo '{}' ';' < /dev/null > out 2> err \
  && grep 'files0.* standard input .*cannot be combined with .*ok' err \
  || { grep . out err; fail=1; }

# Option -files0-from with argument "-" (=stdin) must not be combined with
# the -okdir action: getting the user confirmation would mess with stdin.
returns_ 1 find -files0-from - -okdir echo '{}' ';' < /dev/null > out 2> err \
  && grep 'files0.* standard input .*cannot be combined with .*ok' err \
  || { grep . out err; fail=1; }

# File argument of -files0-from option must not refer to the same file as stdin.
printf '.' > in || framework_failure_
returns_ 1 find -files0-from in -ok echo '{}' ';' < in > out 2> err \
    && grep 'files0.* standard input .*same file .*with -ok, -okdir' err \
  || { grep . out err; fail=1; }

# Likewise via a symlink.
if ln -s in inlink; then
  returns_ 1 find -files0-from inlink -ok echo '{}' ';' < in > out 2> err \
    && grep 'files0.* standard input .*same file .*with -ok, -okdir' err \
    || { grep . out err; fail=1; }
  # ... and vice versa.
  returns_ 1 find -files0-from in -ok echo '{}' ';' < inlink > out 2> err \
    && grep 'files0.* standard input .*same file .*with -ok, -okdir' err \
    || { grep . out err; fail=1; }
fi

# Likewise when the system provides the name '/dev/stdin'.
if ls /dev/stdin >/dev/null 2>&1; then
  returns_ 1 find -files0-from /dev/stdin -ok echo '{}' ';' < in > out 2> err \
    && grep 'files0.* standard input .*same file .*with -ok, -okdir' err \
    || { grep . out err; fail=1; }
fi

# Exercise a non-existing file.
returns_ 1 find -files0-from ENOENT > out 2> err \
  && grep 'cannot open .ENOENT. for reading: No such' err \
  || { grep . out err; fail=1; }

# Exercise a file which cannot be opened.
# The shadow(5) file seems to be a good choice for reasonable coverage.
f='/etc/shadow'
if test -e $f && test '!' -r $f; then
  returns_ 1 find -files0-from $f > out 2> err \
  && grep 'cannot open .* for reading: Permission denied' err \
  || { grep . out err; fail=1; }
fi

# Exercise a directory argument.
returns_ 1 find -files0-from / > out 2> err \
  && grep 'read error' err \
  || { grep . out err; fail=1; }

# Exercise an empty input file.
returns_ 1 find -files0-from /dev/null > out 2> err || fail=1
compare /dev/null out || fail=1
grep 'file with starting points is empty:' err || fail=1

# Likewise via stdin.
returns_ 1 find -files0-from - < /dev/null > out 2> err || fail=1
compare /dev/null out || fail=1
grep 'file with starting points is empty:.*standard input' err || fail=1

# Likewise via a pipe on stdin.
cat /dev/null | returns_ 1 find -files0-from - > out 2> err || fail=1
compare /dev/null out || fail=1
grep 'file with starting points is empty:.*standard input' err || fail=1

# Now a regular case: 2 files: expect the same output.
touch a b || framework_failure_
printf '%s\0' a b > in || framework_failure_
tr '\0' '\n' < in > exp || framework_failure_
find -files0-from in -print > out 2> err || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1

# Demonstrate that -files0-from accepts file names which would otherwise be
# rejected because they are recognized as test or action.
touch ./-print ./-mtime ./-size || framework_failure_
printf '%s\0' _print _mtime _size | tr '_' '-' > in || framework_failure_
tr '\0' '\n' < in > exp || framework_failure_
find -files0-from in -printf '%p\n' > out 2> err || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1

# Zero-length file name on position 2, once per stdin ...
printf '%s\n' a b > exp || framework_failure_
printf '%s\0' a '' b \
  | tee file \
  | returns_ 1 find -files0-from - -print > out 2> err || fail=1
compare exp out || fail=1
grep '(standard input).:2: invalid zero-length file name' err || fail=1
# ... and once per file.
returns_ 1 find -files0-from file -print > out 2> err || fail=1
compare exp out || fail=1
grep 'file.:2: invalid zero-length file name' err || fail=1

# Non-existing file name.
printf '%s\0' a ENOENT b \
  | returns_ 1 find -files0-from - -print > out 2> err || fail=1
compare exp out || fail=1
grep 'ENOENT' err || fail=1

# Demonstrate (the usual!) recursion ...
mkdir d1 d1/d2 d1/d2/d3 && touch d1/d2/d3/file || framework_failure_
printf '%s\n' d1 d1/d2 d1/d2/d3 d1/d2/d3/file > exp || framework_failure_
printf 'd1' \
  | find -files0-from - > out 2> err || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1
# ... and how to avoid recursion with -maxdepth 0.
find d1 -print0 \
  | find -files0-from - -maxdepth 0 > out 2> err || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1

# Large input with files.
# Create file 'exp' with many times its own name as content, NUL-separated;
# and let find(1) check that it worked (4x in bytes).
yes exp | head -n 100000 | tr '\n' '\0' > exp \
  && find exp -size 400000c | grep . || framework_failure_
# Run the test.
find -files0-from exp > out 2> err || fail=1
# ... and verify.
test $( wc -l < out ) = 100000 || fail=1
find out -size 400000c | grep . || fail=1

Exit $fail