xref: /illumos-gate/usr/src/test/util-tests/tests/cpmvln/overwrite.ksh (revision 6cf3cc9d1e40f89e90135a48f74f03f879fce639)
1*6cf3cc9dSRobert Mustacchi#!/usr/bin/ksh
2*6cf3cc9dSRobert Mustacchi#
3*6cf3cc9dSRobert Mustacchi# This file and its contents are supplied under the terms of the
4*6cf3cc9dSRobert Mustacchi# Common Development and Distribution License ("CDDL"), version 1.0.
5*6cf3cc9dSRobert Mustacchi# You may only use this file in accordance with the terms of version
6*6cf3cc9dSRobert Mustacchi# 1.0 of the CDDL.
7*6cf3cc9dSRobert Mustacchi#
8*6cf3cc9dSRobert Mustacchi# A full copy of the text of the CDDL should have accompanied this
9*6cf3cc9dSRobert Mustacchi# source.  A copy of the CDDL is also available via the Internet at
10*6cf3cc9dSRobert Mustacchi# http://www.illumos.org/license/CDDL.
11*6cf3cc9dSRobert Mustacchi#
12*6cf3cc9dSRobert Mustacchi
13*6cf3cc9dSRobert Mustacchi#
14*6cf3cc9dSRobert Mustacchi# Copyright 2024 Oxide Computer Company
15*6cf3cc9dSRobert Mustacchi#
16*6cf3cc9dSRobert Mustacchi
17*6cf3cc9dSRobert Mustacchi#
18*6cf3cc9dSRobert Mustacchi# This test exercises the various overwriting, interactivity, and related
19*6cf3cc9dSRobert Mustacchi# features of cp, mv, and ln (which are all built from the same source). Each
20*6cf3cc9dSRobert Mustacchi# program may be set up to operate interactively (-i), to not touch a file if it
21*6cf3cc9dSRobert Mustacchi# already exists (-n), and to forcefully remove it anyways (-f). cp implements
22*6cf3cc9dSRobert Mustacchi# -i and -n, -f means something different. mv implements all three flags. ln
23*6cf3cc9dSRobert Mustacchi# implements -i and -f (-n is a pseudo-default).
24*6cf3cc9dSRobert Mustacchi#
25*6cf3cc9dSRobert Mustacchi
26*6cf3cc9dSRobert Mustacchiunalias -a
27*6cf3cc9dSRobert Mustacchiset -o pipefail
28*6cf3cc9dSRobert Mustacchiexport LANG=C.UTF-8
29*6cf3cc9dSRobert Mustacchi
30*6cf3cc9dSRobert Mustacchi#
31*6cf3cc9dSRobert Mustacchi# Program paths for interposing while testing.
32*6cf3cc9dSRobert Mustacchi#
33*6cf3cc9dSRobert MustacchiMV=${MV:-"/usr/bin/mv"}
34*6cf3cc9dSRobert MustacchiXMV=${XMV:-"/usr/xpg4/bin/mv"}
35*6cf3cc9dSRobert MustacchiCP=${CP:-"/usr/bin/cp"}
36*6cf3cc9dSRobert MustacchiXCP=${XCP:-"/usr/xpg4/bin/cp"}
37*6cf3cc9dSRobert MustacchiLN=${LN:-"/usr/bin/ln"}
38*6cf3cc9dSRobert MustacchiXLN=${XLN:-"/usr/xpg4/bin/ln"}
39*6cf3cc9dSRobert Mustacchi
40*6cf3cc9dSRobert Mustacchiovr_exit=0
41*6cf3cc9dSRobert Mustacchiovr_arg0=$(basename $0)
42*6cf3cc9dSRobert Mustacchiovr_tdir=$(dirname $0)
43*6cf3cc9dSRobert Mustacchiovr_mkobj="$ovr_tdir/mkobj"
44*6cf3cc9dSRobert Mustacchiovr_check="$ovr_tdir/checker"
45*6cf3cc9dSRobert Mustacchiovr_work="/tmp/$ovr_arg0.$$"
46*6cf3cc9dSRobert Mustacchi
47*6cf3cc9dSRobert Mustacchitypeset -A ovr_files=(
48*6cf3cc9dSRobert Mustacchi	["a"]=(type="file" path="$ovr_work/a")
49*6cf3cc9dSRobert Mustacchi	["b"]=(type="file" path="$ovr_work/b")
50*6cf3cc9dSRobert Mustacchi	["c"]=(type="noperms" path="$ovr_work/c")
51*6cf3cc9dSRobert Mustacchi	["fifo"]=(type="fifo" path="$ovr_work/fifo")
52*6cf3cc9dSRobert Mustacchi	["door"]=(type="door" path="$ovr_work/door")
53*6cf3cc9dSRobert Mustacchi	["uds"]=(type="uds" path="$ovr_work/uds")
54*6cf3cc9dSRobert Mustacchi	["symlink"]=(type="symlink" path="$ovr_work/symlink")
55*6cf3cc9dSRobert Mustacchi	["dangle"]=(type="dangle" path="$ovr_work/dangle")
56*6cf3cc9dSRobert Mustacchi	["dir"]=(type="dir" path="$ovr_work/dir")
57*6cf3cc9dSRobert Mustacchi	["dir/a"]=(type="file-dm" path="$ovr_work/dir/a")
58*6cf3cc9dSRobert Mustacchi	["dir/b"]=(type="empty" path="$ovr_work/dir/b")
59*6cf3cc9dSRobert Mustacchi	["dir/c"]=(type="noperms-dm" path="$ovr_work/dir/c")
60*6cf3cc9dSRobert Mustacchi	["dir/fifo"]=(type="fifo-dm" path="$ovr_work/dir/fifo")
61*6cf3cc9dSRobert Mustacchi	["dir/door"]=(type="door-dm" path="$ovr_work/dir/door")
62*6cf3cc9dSRobert Mustacchi	["dir/uds"]=(type="uds-dm" path="$ovr_work/dir/uds")
63*6cf3cc9dSRobert Mustacchi	["dir/symlink"]=(type="symlink-dm" path="$ovr_work/dir/symlink")
64*6cf3cc9dSRobert Mustacchi	["dir/dangle"]=(type="dangle-dm" path="$ovr_work/dir/dangle")
65*6cf3cc9dSRobert Mustacchi)
66*6cf3cc9dSRobert Mustacchi
67*6cf3cc9dSRobert Mustacchifunction fatal
68*6cf3cc9dSRobert Mustacchi{
69*6cf3cc9dSRobert Mustacchi	typeset msg="$*"
70*6cf3cc9dSRobert Mustacchi	echo "TEST FAILED: $msg" >&2
71*6cf3cc9dSRobert Mustacchi	exit 1
72*6cf3cc9dSRobert Mustacchi}
73*6cf3cc9dSRobert Mustacchi
74*6cf3cc9dSRobert Mustacchifunction warn
75*6cf3cc9dSRobert Mustacchi{
76*6cf3cc9dSRobert Mustacchi	typeset msg="$*"
77*6cf3cc9dSRobert Mustacchi	echo "TEST FAILED: $msg" >&2
78*6cf3cc9dSRobert Mustacchi	ovr_exit=1
79*6cf3cc9dSRobert Mustacchi}
80*6cf3cc9dSRobert Mustacchi
81*6cf3cc9dSRobert Mustacchifunction cleanup
82*6cf3cc9dSRobert Mustacchi{
83*6cf3cc9dSRobert Mustacchi	rm -rf $ovr_work/
84*6cf3cc9dSRobert Mustacchi}
85*6cf3cc9dSRobert Mustacchi
86*6cf3cc9dSRobert Mustacchi#
87*6cf3cc9dSRobert Mustacchi# Make the files that are required for this particular test.
88*6cf3cc9dSRobert Mustacchi#
89*6cf3cc9dSRobert Mustacchifunction setup_files
90*6cf3cc9dSRobert Mustacchi{
91*6cf3cc9dSRobert Mustacchi	mkdir "$ovr_work" || fatal "failed to make test directory"
92*6cf3cc9dSRobert Mustacchi	for f in $@; do
93*6cf3cc9dSRobert Mustacchi		typeset targ=${ovr_files[$f].path}
94*6cf3cc9dSRobert Mustacchi		typeset ftype=${ovr_files[$f].type}
95*6cf3cc9dSRobert Mustacchi		case $ftype in
96*6cf3cc9dSRobert Mustacchi		file)
97*6cf3cc9dSRobert Mustacchi			echo $f > $targ || fatal "failed to create $f"
98*6cf3cc9dSRobert Mustacchi			;;
99*6cf3cc9dSRobert Mustacchi		empty)
100*6cf3cc9dSRobert Mustacchi			touch $targ || fatal "failed to create $f"
101*6cf3cc9dSRobert Mustacchi			;;
102*6cf3cc9dSRobert Mustacchi		noperms)
103*6cf3cc9dSRobert Mustacchi			echo $f > $targ || fatal "failed to create $f"
104*6cf3cc9dSRobert Mustacchi			chmod 0000 $targ || fatal "failed to chmod $f"
105*6cf3cc9dSRobert Mustacchi			;;
106*6cf3cc9dSRobert Mustacchi		fifo)
107*6cf3cc9dSRobert Mustacchi			$ovr_mkobj -f $targ || fatal "failed to make fifo"
108*6cf3cc9dSRobert Mustacchi			;;
109*6cf3cc9dSRobert Mustacchi		door)
110*6cf3cc9dSRobert Mustacchi			$ovr_mkobj -d $targ || fatal "failed to make door"
111*6cf3cc9dSRobert Mustacchi			;;
112*6cf3cc9dSRobert Mustacchi		uds)
113*6cf3cc9dSRobert Mustacchi			$ovr_mkobj -s $targ || fatal "failed to make uds"
114*6cf3cc9dSRobert Mustacchi			;;
115*6cf3cc9dSRobert Mustacchi		symlink)
116*6cf3cc9dSRobert Mustacchi			ln -s ${ovr_files["b"].path} $targ || \
117*6cf3cc9dSRobert Mustacchi			    fatal "failed to make symlink"
118*6cf3cc9dSRobert Mustacchi			;;
119*6cf3cc9dSRobert Mustacchi		dangle)
120*6cf3cc9dSRobert Mustacchi			ln -s "$ovr_work/enoent" $targ || \
121*6cf3cc9dSRobert Mustacchi			     fatal "failed to make dangling symlink"
122*6cf3cc9dSRobert Mustacchi			;;
123*6cf3cc9dSRobert Mustacchi		dir)
124*6cf3cc9dSRobert Mustacchi			mkdir -p $targ || fatal "failed to make directory"
125*6cf3cc9dSRobert Mustacchi			;;
126*6cf3cc9dSRobert Mustacchi		*)
127*6cf3cc9dSRobert Mustacchi			fatal "encountered unknown type $f: $ftype"
128*6cf3cc9dSRobert Mustacchi		esac
129*6cf3cc9dSRobert Mustacchi	done
130*6cf3cc9dSRobert Mustacchi}
131*6cf3cc9dSRobert Mustacchi
132*6cf3cc9dSRobert Mustacchi#
133*6cf3cc9dSRobert Mustacchi# Check files remain what we expect at this point. Arguments passed should be
134*6cf3cc9dSRobert Mustacchi# the short form.
135*6cf3cc9dSRobert Mustacchi#
136*6cf3cc9dSRobert Mustacchifunction check_files
137*6cf3cc9dSRobert Mustacchi{
138*6cf3cc9dSRobert Mustacchi	typeset desc=$1
139*6cf3cc9dSRobert Mustacchi	shift
140*6cf3cc9dSRobert Mustacchi	for f in $@; do
141*6cf3cc9dSRobert Mustacchi		typeset targ=${ovr_files[$f].path}
142*6cf3cc9dSRobert Mustacchi		typeset ftype=${ovr_files[$f].type}
143*6cf3cc9dSRobert Mustacchi		typeset data=
144*6cf3cc9dSRobert Mustacchi		case $ftype in
145*6cf3cc9dSRobert Mustacchi		file*)
146*6cf3cc9dSRobert Mustacchi			#
147*6cf3cc9dSRobert Mustacchi			# A file should have the data that matches its short
148*6cf3cc9dSRobert Mustacchi			# name inside of it.
149*6cf3cc9dSRobert Mustacchi			#
150*6cf3cc9dSRobert Mustacchi			typeset exp=${f##*/}
151*6cf3cc9dSRobert Mustacchi			data=$(cat $targ)
152*6cf3cc9dSRobert Mustacchi			if [[ $data != $exp ]]; then
153*6cf3cc9dSRobert Mustacchi				warn "$desc: found unexpected file data $data" \
154*6cf3cc9dSRobert Mustacchi				    "expected $exp"
155*6cf3cc9dSRobert Mustacchi				return 1
156*6cf3cc9dSRobert Mustacchi			fi
157*6cf3cc9dSRobert Mustacchi			;;
158*6cf3cc9dSRobert Mustacchi		noperms*)
159*6cf3cc9dSRobert Mustacchi			if ! $ovr_check -n $targ; then
160*6cf3cc9dSRobert Mustacchi				warn "$desc: $targ was clobbered"
161*6cf3cc9dSRobert Mustacchi				return 1
162*6cf3cc9dSRobert Mustacchi			fi
163*6cf3cc9dSRobert Mustacchi			;;
164*6cf3cc9dSRobert Mustacchi		fifo*)
165*6cf3cc9dSRobert Mustacchi			if [[ ! -p $targ ]]; then
166*6cf3cc9dSRobert Mustacchi				warn "$desc: $targ was is somehow no longer" \
167*6cf3cc9dSRobert Mustacchi				    "a pipe: $(ls -l $targ)"
168*6cf3cc9dSRobert Mustacchi				return 1
169*6cf3cc9dSRobert Mustacchi			fi
170*6cf3cc9dSRobert Mustacchi			;;
171*6cf3cc9dSRobert Mustacchi		door*)
172*6cf3cc9dSRobert Mustacchi			if ! $ovr_check -d $targ; then
173*6cf3cc9dSRobert Mustacchi				warn "$desc: $targ was clobbered"
174*6cf3cc9dSRobert Mustacchi				return 1
175*6cf3cc9dSRobert Mustacchi			fi
176*6cf3cc9dSRobert Mustacchi			;;
177*6cf3cc9dSRobert Mustacchi		uds*)
178*6cf3cc9dSRobert Mustacchi			if [[ ! -S $targ ]]; then
179*6cf3cc9dSRobert Mustacchi				warn "$desc: $targ was is somehow no longer" \
180*6cf3cc9dSRobert Mustacchi				    "a socket: $(ls -l $targ)"
181*6cf3cc9dSRobert Mustacchi				return 1
182*6cf3cc9dSRobert Mustacchi			fi
183*6cf3cc9dSRobert Mustacchi			;;
184*6cf3cc9dSRobert Mustacchi		symlink*|dangle*)
185*6cf3cc9dSRobert Mustacchi			if [[ ! -L $targ ]]; then
186*6cf3cc9dSRobert Mustacchi				warn "$desc: $targ was is somehow no longer" \
187*6cf3cc9dSRobert Mustacchi				    "a symlink: $(ls -l $targ)"
188*6cf3cc9dSRobert Mustacchi				return 1
189*6cf3cc9dSRobert Mustacchi			fi
190*6cf3cc9dSRobert Mustacchi			;;
191*6cf3cc9dSRobert Mustacchi		dir)
192*6cf3cc9dSRobert Mustacchi			if [[ ! -d $targ ]]; then
193*6cf3cc9dSRobert Mustacchi				warn "$desc: directory $targ was removed?!"
194*6cf3cc9dSRobert Mustacchi				return 1
195*6cf3cc9dSRobert Mustacchi			fi
196*6cf3cc9dSRobert Mustacchi			;;
197*6cf3cc9dSRobert Mustacchi		*)
198*6cf3cc9dSRobert Mustacchi			fatal "encountered unknown type $f: $ftype"
199*6cf3cc9dSRobert Mustacchi		esac
200*6cf3cc9dSRobert Mustacchi	done
201*6cf3cc9dSRobert Mustacchi
202*6cf3cc9dSRobert Mustacchi	return 0
203*6cf3cc9dSRobert Mustacchi}
204*6cf3cc9dSRobert Mustacchi
205*6cf3cc9dSRobert Mustacchifunction check_data
206*6cf3cc9dSRobert Mustacchi{
207*6cf3cc9dSRobert Mustacchi	typeset desc=$1
208*6cf3cc9dSRobert Mustacchi	typeset targ=$2
209*6cf3cc9dSRobert Mustacchi	typeset expect=$3
210*6cf3cc9dSRobert Mustacchi	typeset data=
211*6cf3cc9dSRobert Mustacchi
212*6cf3cc9dSRobert Mustacchi	data=$(cat $targ)
213*6cf3cc9dSRobert Mustacchi	if [[ $data != $expect ]]; then
214*6cf3cc9dSRobert Mustacchi		warn "$desc: $targ wasn't overwritten found $data"
215*6cf3cc9dSRobert Mustacchi		return 1;
216*6cf3cc9dSRobert Mustacchi	fi
217*6cf3cc9dSRobert Mustacchi
218*6cf3cc9dSRobert Mustacchi	return 0
219*6cf3cc9dSRobert Mustacchi}
220*6cf3cc9dSRobert Mustacchi
221*6cf3cc9dSRobert Mustacchi#
222*6cf3cc9dSRobert Mustacchi# Run a test we expect to fail and verify that files haven't changed.
223*6cf3cc9dSRobert Mustacchi#
224*6cf3cc9dSRobert Mustacchifunction exp_fail
225*6cf3cc9dSRobert Mustacchi{
226*6cf3cc9dSRobert Mustacchi	typeset desc="$1"
227*6cf3cc9dSRobert Mustacchi	typeset prog="$2"
228*6cf3cc9dSRobert Mustacchi	typeset files="$3"
229*6cf3cc9dSRobert Mustacchi	typeset -a args
230*6cf3cc9dSRobert Mustacchi
231*6cf3cc9dSRobert Mustacchi	setup_files $files
232*6cf3cc9dSRobert Mustacchi	for f in $files; do
233*6cf3cc9dSRobert Mustacchi		args+=(${ovr_files[$f].path})
234*6cf3cc9dSRobert Mustacchi	done
235*6cf3cc9dSRobert Mustacchi
236*6cf3cc9dSRobert Mustacchi	if $prog ${args[@]} 2>/dev/null; then
237*6cf3cc9dSRobert Mustacchi		warn "$desc: command returned 0, but expected failure"
238*6cf3cc9dSRobert Mustacchi		cleanup
239*6cf3cc9dSRobert Mustacchi		return
240*6cf3cc9dSRobert Mustacchi	fi
241*6cf3cc9dSRobert Mustacchi
242*6cf3cc9dSRobert Mustacchi	check_files "$desc" "$files" && printf "TEST PASSED: %s\n" "$desc"
243*6cf3cc9dSRobert Mustacchi	cleanup
244*6cf3cc9dSRobert Mustacchi}
245*6cf3cc9dSRobert Mustacchi
246*6cf3cc9dSRobert Mustacchi#
247*6cf3cc9dSRobert Mustacchi# Run a test where we want to check a particular file's contents after the test
248*6cf3cc9dSRobert Mustacchi# passes. The optional last pipe argument is used for testing interactive mode
249*6cf3cc9dSRobert Mustacchi# (whether or not a prompt appears is a different question). Interactive mode
250*6cf3cc9dSRobert Mustacchi# requires we don't have pipefail turned on to avoid propagating an error when
251*6cf3cc9dSRobert Mustacchi# the initial program gets EPIPE or a signal.
252*6cf3cc9dSRobert Mustacchi#
253*6cf3cc9dSRobert Mustacchifunction exp_pass
254*6cf3cc9dSRobert Mustacchi{
255*6cf3cc9dSRobert Mustacchi	typeset desc="$1"
256*6cf3cc9dSRobert Mustacchi	typeset prog="$2"
257*6cf3cc9dSRobert Mustacchi	typeset files="$3"
258*6cf3cc9dSRobert Mustacchi	typeset expect="$4"
259*6cf3cc9dSRobert Mustacchi	typeset pipe="$5"
260*6cf3cc9dSRobert Mustacchi	typeset ret=
261*6cf3cc9dSRobert Mustacchi	typeset -a args
262*6cf3cc9dSRobert Mustacchi
263*6cf3cc9dSRobert Mustacchi	setup_files $files
264*6cf3cc9dSRobert Mustacchi	for f in $files; do
265*6cf3cc9dSRobert Mustacchi		args+=(${ovr_files[$f].path})
266*6cf3cc9dSRobert Mustacchi	done
267*6cf3cc9dSRobert Mustacchi
268*6cf3cc9dSRobert Mustacchi	if [[ -z "$pipe" ]]; then
269*6cf3cc9dSRobert Mustacchi		$prog ${args[@]}
270*6cf3cc9dSRobert Mustacchi		ret=$?
271*6cf3cc9dSRobert Mustacchi	else
272*6cf3cc9dSRobert Mustacchi		set +o pipefail
273*6cf3cc9dSRobert Mustacchi		$pipe | $prog ${args[@]} 2>/dev/null
274*6cf3cc9dSRobert Mustacchi		ret=$?
275*6cf3cc9dSRobert Mustacchi		set -o pipefail
276*6cf3cc9dSRobert Mustacchi	fi
277*6cf3cc9dSRobert Mustacchi
278*6cf3cc9dSRobert Mustacchi	if (( ret != 0 )); then
279*6cf3cc9dSRobert Mustacchi		warn "$desc: command failed, but expected success"
280*6cf3cc9dSRobert Mustacchi		cleanup
281*6cf3cc9dSRobert Mustacchi		return
282*6cf3cc9dSRobert Mustacchi	fi
283*6cf3cc9dSRobert Mustacchi
284*6cf3cc9dSRobert Mustacchi	check_data "$desc" "${args[-1]}" "$expect" && \
285*6cf3cc9dSRobert Mustacchi	    printf "TEST PASSED: %s\n" "$desc"
286*6cf3cc9dSRobert Mustacchi	cleanup
287*6cf3cc9dSRobert Mustacchi}
288*6cf3cc9dSRobert Mustacchi
289*6cf3cc9dSRobert Mustacchi#
290*6cf3cc9dSRobert Mustacchi# Variant on exp_pass that expects all the input files to remain the same.
291*6cf3cc9dSRobert Mustacchi#
292*6cf3cc9dSRobert Mustacchifunction exp_retain
293*6cf3cc9dSRobert Mustacchi{
294*6cf3cc9dSRobert Mustacchi	typeset desc="$1"
295*6cf3cc9dSRobert Mustacchi	typeset prog="$2"
296*6cf3cc9dSRobert Mustacchi	typeset files="$3"
297*6cf3cc9dSRobert Mustacchi	typeset -a args
298*6cf3cc9dSRobert Mustacchi
299*6cf3cc9dSRobert Mustacchi	setup_files $files
300*6cf3cc9dSRobert Mustacchi	for f in $files; do
301*6cf3cc9dSRobert Mustacchi		args+=(${ovr_files[$f].path})
302*6cf3cc9dSRobert Mustacchi	done
303*6cf3cc9dSRobert Mustacchi
304*6cf3cc9dSRobert Mustacchi	if ! $prog ${args[@]}; then
305*6cf3cc9dSRobert Mustacchi		warn "$desc: command failed, but expected success"
306*6cf3cc9dSRobert Mustacchi		cleanup
307*6cf3cc9dSRobert Mustacchi		return
308*6cf3cc9dSRobert Mustacchi	fi
309*6cf3cc9dSRobert Mustacchi
310*6cf3cc9dSRobert Mustacchi	if check_files "$desc" "$files"; then
311*6cf3cc9dSRobert Mustacchi		printf "TEST PASSED: %s\n" "$desc"
312*6cf3cc9dSRobert Mustacchi	fi
313*6cf3cc9dSRobert Mustacchi	cleanup
314*6cf3cc9dSRobert Mustacchi}
315*6cf3cc9dSRobert Mustacchi
316*6cf3cc9dSRobert Mustacchi#
317*6cf3cc9dSRobert Mustacchi# Tests for a directory. We always set up the files in the directory in addition
318*6cf3cc9dSRobert Mustacchi# to what was asked for. Then based on our expectations we make sure that the
319*6cf3cc9dSRobert Mustacchi# files were created that we expect. All tests in here should succeed.
320*6cf3cc9dSRobert Mustacchi#
321*6cf3cc9dSRobert Mustacchifunction exp_dir
322*6cf3cc9dSRobert Mustacchi{
323*6cf3cc9dSRobert Mustacchi	typeset desc="$1"
324*6cf3cc9dSRobert Mustacchi	typeset prog="$2"
325*6cf3cc9dSRobert Mustacchi	typeset files="$3"
326*6cf3cc9dSRobert Mustacchi	typeset rval="$4"
327*6cf3cc9dSRobert Mustacchi	typeset exp="$5"
328*6cf3cc9dSRobert Mustacchi	typeset bdata="$6"
329*6cf3cc9dSRobert Mustacchi	typeset pipe="$7"
330*6cf3cc9dSRobert Mustacchi	typeset pass=0
331*6cf3cc9dSRobert Mustacchi	typeset -a args
332*6cf3cc9dSRobert Mustacchi
333*6cf3cc9dSRobert Mustacchi	setup_files $files dir dir/b
334*6cf3cc9dSRobert Mustacchi	for f in $files; do
335*6cf3cc9dSRobert Mustacchi		args+=(${ovr_files[$f].path})
336*6cf3cc9dSRobert Mustacchi	done
337*6cf3cc9dSRobert Mustacchi
338*6cf3cc9dSRobert Mustacchi	if [[ -z "$pipe" ]]; then
339*6cf3cc9dSRobert Mustacchi		$prog ${args[@]} 2>/dev/null
340*6cf3cc9dSRobert Mustacchi		ret=$?
341*6cf3cc9dSRobert Mustacchi	else
342*6cf3cc9dSRobert Mustacchi		set +o pipefail
343*6cf3cc9dSRobert Mustacchi		$pipe | $prog ${args[@]} 2>/dev/null
344*6cf3cc9dSRobert Mustacchi		ret=$?
345*6cf3cc9dSRobert Mustacchi		set -o pipefail
346*6cf3cc9dSRobert Mustacchi	fi
347*6cf3cc9dSRobert Mustacchi
348*6cf3cc9dSRobert Mustacchi	if (( ret != rval )); then
349*6cf3cc9dSRobert Mustacchi		warn "$desc: command returned $ret, but expected $rval"
350*6cf3cc9dSRobert Mustacchi		cleanup
351*6cf3cc9dSRobert Mustacchi		return
352*6cf3cc9dSRobert Mustacchi	fi
353*6cf3cc9dSRobert Mustacchi
354*6cf3cc9dSRobert Mustacchi	if (( ret != 0 )); then
355*6cf3cc9dSRobert Mustacchi		cleanup
356*6cf3cc9dSRobert Mustacchi		return;
357*6cf3cc9dSRobert Mustacchi	fi
358*6cf3cc9dSRobert Mustacchi
359*6cf3cc9dSRobert Mustacchi	check_files "$desc" $exp || pass=1
360*6cf3cc9dSRobert Mustacchi	check_data "$desc" "${ovr_files[dir/b].path}" "$bdata" || pass=1
361*6cf3cc9dSRobert Mustacchi	(( pass == 0 )) && printf "TEST PASSED: %s\n" "$desc"
362*6cf3cc9dSRobert Mustacchi	cleanup
363*6cf3cc9dSRobert Mustacchi}
364*6cf3cc9dSRobert Mustacchi
365*6cf3cc9dSRobert Mustacchitrap cleanup EXIT
366*6cf3cc9dSRobert Mustacchi
367*6cf3cc9dSRobert Mustacchi#
368*6cf3cc9dSRobert Mustacchi# Start with ln which should fail without -f. Same with ln -s (a different code
369*6cf3cc9dSRobert Mustacchi# path).
370*6cf3cc9dSRobert Mustacchi#
371*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a file (ln a b)" "$LN" "a b"
372*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a file without perms (ln a c)" "$LN" "a c"
373*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a uds (ln a uds)" "$LN" "a uds"
374*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a fifo (ln a fifo)" "$LN" "a fifo"
375*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a door (ln a door)" "$LN" "a door"
376*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a valid symlink (ln a symlink)" "$LN" "a symlink"
377*6cf3cc9dSRobert Mustacchiexp_fail "ln doesn't clobber a dangling symlink (ln a dangle)" "$LN" "a dangle"
378*6cf3cc9dSRobert Mustacchi
379*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a file (ln -s a b)" "$LN -s" "a b"
380*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a file without perms (ln -s a c)" "$LN -s" "a c"
381*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a uds (ln -s a uds)" "$LN -s" "a uds"
382*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a fifo (ln -s a fifo)" "$LN -s" "a fifo"
383*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a door (ln -s a door)" "$LN -s" "a door"
384*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a valid symlink (ln -s a symlink)" "$LN -s" \
385*6cf3cc9dSRobert Mustacchi    "a symlink"
386*6cf3cc9dSRobert Mustacchiexp_fail "ln -s doesn't clobber a dangling symlink (ln -s a dangle)" "$LN -s" \
387*6cf3cc9dSRobert Mustacchi    "a dangle"
388*6cf3cc9dSRobert Mustacchi
389*6cf3cc9dSRobert Mustacchi#
390*6cf3cc9dSRobert Mustacchi# Now basic cp tests. We expect cp to fail on most of these because it doesn't
391*6cf3cc9dSRobert Mustacchi# have -f specified and therefore can't open the file without permissions or
392*6cf3cc9dSRobert Mustacchi# replace and deal with the socket and door. We don't use the fifo because it
393*6cf3cc9dSRobert Mustacchi# will basically just cause us to block.
394*6cf3cc9dSRobert Mustacchi#
395*6cf3cc9dSRobert Mustacchiexp_pass "cp works on a file (cp a b)" "$CP" "a b" "a"
396*6cf3cc9dSRobert Mustacchiexp_pass "XPG cp works on a file (cp a b)" "$XCP" "a b" "a"
397*6cf3cc9dSRobert Mustacchiexp_fail "cp fails on a file without perms (cp a c)" "$CP" "a c"
398*6cf3cc9dSRobert Mustacchiexp_fail "XPG cp fails on a file without perms (cp a c)" "$XCP" "a c"
399*6cf3cc9dSRobert Mustacchiexp_fail "cp fails on a uds (cp a sock)" "$CP" "a uds"
400*6cf3cc9dSRobert Mustacchiexp_fail "cp fails on a door (cp a door)" "$CP" "a door"
401*6cf3cc9dSRobert Mustacchiexp_pass "cp works on a symlink (cp a symlink)" "$CP" "a symlink" "a"
402*6cf3cc9dSRobert Mustacchiexp_pass "cp works on a dangling symlink (cp a dangle)" "$CP" "a dangle" "a"
403*6cf3cc9dSRobert Mustacchi
404*6cf3cc9dSRobert Mustacchi#
405*6cf3cc9dSRobert Mustacchi# Basic mv tests. We expect mv to work on most things, but the door is a bit
406*6cf3cc9dSRobert Mustacchi# complicated because rename will fail with EBUSY, but that depends on the file
407*6cf3cc9dSRobert Mustacchi# system unfortunately (seems to fail on ZFS but work on tmpfs).
408*6cf3cc9dSRobert Mustacchi#
409*6cf3cc9dSRobert Mustacchiexp_pass "mv works on a file (mv a b)" "$MV" "a b" "a"
410*6cf3cc9dSRobert Mustacchiexp_pass "mv works on a fifo (mv a fifo)" "$MV" "a fifo" "a"
411*6cf3cc9dSRobert Mustacchiexp_pass "mv works on a uds (mv a sock)" "$MV" "a uds" "a"
412*6cf3cc9dSRobert Mustacchiexp_pass "mv works on a symlink (mv a symlink)" "$MV" "a symlink" "a"
413*6cf3cc9dSRobert Mustacchiexp_pass "mv works on a dangling symlink (mv a dangle)" "$MV" "a dangle" "a"
414*6cf3cc9dSRobert Mustacchi
415*6cf3cc9dSRobert Mustacchi#
416*6cf3cc9dSRobert Mustacchi# Now we go into -f versions and cases where -f trumps -i. This should cause
417*6cf3cc9dSRobert Mustacchi# everything to work for ln. For cp, the fifo and door will not work because it
418*6cf3cc9dSRobert Mustacchi# will not remove them. We don't test the fifo due to hangs. For mv we expect
419*6cf3cc9dSRobert Mustacchi# everything expect the door (which we skip) to work.
420*6cf3cc9dSRobert Mustacchi#
421*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a file (ln -f a b)" "$LN -f" "a b" "a"
422*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a file without perms (ln -f a c)" "$LN -f" "a c" "a"
423*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a uds (ln -f a uds)" "$LN -f" "a uds" "a"
424*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a fifo (ln -f a fifo)" "$LN -f" "a fifo" "a"
425*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a door (ln -f a door)" "$LN -f" "a door" "a"
426*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobbers a valid symlink (ln -f a symlink)" "$LN -f" \
427*6cf3cc9dSRobert Mustacchi    "a symlink" "a"
428*6cf3cc9dSRobert Mustacchiexp_pass "ln -f clobber a dangling symlink (ln -f a dangle)" "$LN -f" \
429*6cf3cc9dSRobert Mustacchi    "a dangle" "a"
430*6cf3cc9dSRobert Mustacchiexp_pass "ln -f beats -i on a file (ln -if a b)" "$LN -if" "a b" "a"
431*6cf3cc9dSRobert Mustacchiexp_pass "ln -f beats -i on a file (ln -ifif a b)" "$LN -ifif" "a b" "a"
432*6cf3cc9dSRobert Mustacchi
433*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a file (ln -sf a b)" "$LN -sf" "a b" "a"
434*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a file without perms (ln -sf a c)" "$LN -sf" "a c" "a"
435*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a uds (ln -sf a uds)" "$LN -sf" "a uds" "a"
436*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a fifo (ln -sf a fifo)" "$LN -sf" "a fifo" "a"
437*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a door (ln -sf a door)" "$LN -sf" "a door" "a"
438*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobbers a valid symlink (ln -sf a symlink)" "$LN -sf" \
439*6cf3cc9dSRobert Mustacchi    "a symlink" "a"
440*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf clobber a dangling symlink (ln -sf a dangle)" "$LN -sf" \
441*6cf3cc9dSRobert Mustacchi    "a dangle" "a"
442*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf beats -i on a file (ln -s -if a b)" "$LN -s -if" "a b" "a"
443*6cf3cc9dSRobert Mustacchiexp_pass "ln -sf beats -i on a file (ln -s -ifif a b)" "$LN -s -ifif" "a b" "a"
444*6cf3cc9dSRobert Mustacchi
445*6cf3cc9dSRobert Mustacchi
446*6cf3cc9dSRobert Mustacchiexp_pass "cp -f clobbers a file (cp -f a b)" "$CP -f" "a b" "a"
447*6cf3cc9dSRobert Mustacchiexp_pass "cp -f clobbers a file without perms (cp -f a c)" "$CP -f" "a c" "a"
448*6cf3cc9dSRobert Mustacchiexp_pass "cp -f clobbers a uds (cp -f a uds)" "$CP -f" "a uds" "a"
449*6cf3cc9dSRobert Mustacchiexp_fail "cp -f leaves a door alone (cp -f a door)" "$CP -f" "a door" "a"
450*6cf3cc9dSRobert Mustacchiexp_pass "cp -f clobbers a valid symlink (cp -f a symlink)" "$CP -f" \
451*6cf3cc9dSRobert Mustacchi    "a symlink" "a"
452*6cf3cc9dSRobert Mustacchiexp_pass "cp -f clobber a dangling symlink (cp -f a dangle)" "$CP -f" \
453*6cf3cc9dSRobert Mustacchi    "a dangle" "a"
454*6cf3cc9dSRobert Mustacchi
455*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobbers a file (mv -f a b)" "$MV -f" "a b" "a"
456*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobbers a file without perms (mv -f a c)" "$MV -f" "a c" "a"
457*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobbers a uds (mv -f a uds)" "$MV -f" "a uds" "a"
458*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobbers a fifo (mv -f a fifo)" "$MV -f" "a fifo" "a"
459*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobbers a valid symlink (mv -f a symlink)" "$MV -f" \
460*6cf3cc9dSRobert Mustacchi    "a symlink" "a"
461*6cf3cc9dSRobert Mustacchiexp_pass "mv -f clobber a dangling symlink (mv -f a dangle)" "$MV -f" \
462*6cf3cc9dSRobert Mustacchi    "a dangle" "a"
463*6cf3cc9dSRobert Mustacchi
464*6cf3cc9dSRobert Mustacchi#
465*6cf3cc9dSRobert Mustacchi# Now cp and mv -n tests. These should leave the target file as is, but pass.
466*6cf3cc9dSRobert Mustacchi#
467*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a file (cp -n a b)" "$CP -n" "a b"
468*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a file without perms (cp -n a c)" "$CP -n" \
469*6cf3cc9dSRobert Mustacchi    "a c"
470*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a uds (cp -n a uds)" "$CP -n" "a uds"
471*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a fifo (cp -n a fifo)" "$CP -n" "a fifo"
472*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a door (cp -n a door)" "$CP -n" "a door"
473*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a valid symlink (cp -n a symlink)" "$CP -n" \
474*6cf3cc9dSRobert Mustacchi    "a symlink"
475*6cf3cc9dSRobert Mustacchiexp_retain "cp -n doesn't clobber a dangling symlink (cp -n a dangle)" \
476*6cf3cc9dSRobert Mustacchi    "$CP -n" "a dangle"
477*6cf3cc9dSRobert Mustacchi
478*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a file (mv -n a b)" "$MV -n" "a b"
479*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a file without perms (mv -n a c)" "$MV -n" \
480*6cf3cc9dSRobert Mustacchi    "a c"
481*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a uds (mv -n a uds)" "$MV -n" "a uds"
482*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a fifo (mv -n a fifo)" "$MV -n" "a fifo"
483*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a door (mv -n a door)" "$MV -n" "a door"
484*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a valid symlink (mv -n a symlink)" "$MV -n" \
485*6cf3cc9dSRobert Mustacchi    "a symlink"
486*6cf3cc9dSRobert Mustacchiexp_retain "mv -n doesn't clobber a dangling symlink (mv -n a dangle)" \
487*6cf3cc9dSRobert Mustacchi    "$MV -n" "a dangle"
488*6cf3cc9dSRobert Mustacchi
489*6cf3cc9dSRobert Mustacchi#
490*6cf3cc9dSRobert Mustacchi# -n, -f, and -i interleaving. None of these should cause prompts. non-XPG mv -f
491*6cf3cc9dSRobert Mustacchi# will trump -i anywhere. XPG mv -i working normally is tested later on.
492*6cf3cc9dSRobert Mustacchi#
493*6cf3cc9dSRobert Mustacchiexp_retain "cp -n always beats -f (cp -nf a b)" "$CP -nf" "a b"
494*6cf3cc9dSRobert Mustacchiexp_retain "cp -n always beats -f (cp -fn a b)" "$CP -fn" "a b"
495*6cf3cc9dSRobert Mustacchiexp_retain "cp last -n wins (cp -in a b)" "$CP -in" "a b"
496*6cf3cc9dSRobert Mustacchiexp_retain "cp last -n wins (cp -nin a b)" "$CP -nin" "a b"
497*6cf3cc9dSRobert Mustacchi
498*6cf3cc9dSRobert Mustacchiexp_retain "mv last -n wins (mv -in a b)" "$MV -in" "a b"
499*6cf3cc9dSRobert Mustacchiexp_retain "mv last -n wins (mv -fn a b)" "$MV -fn" "a b"
500*6cf3cc9dSRobert Mustacchiexp_retain "mv last -n wins (mv -ifn a b)" "$MV -ifn" "a b"
501*6cf3cc9dSRobert Mustacchiexp_retain "mv last -n wins (mv -fifn a b)" "$MV -fifn" "a b"
502*6cf3cc9dSRobert Mustacchiexp_pass "mv last -f wins (mv -nf a b)" "$MV -nf" "a b" "a"
503*6cf3cc9dSRobert Mustacchiexp_pass "mv last -f wins (mv -if a b)" "$MV -if" "a b" "a"
504*6cf3cc9dSRobert Mustacchiexp_pass "mv last -f wins (mv -fif a b)" "$MV -fif" "a b" "a"
505*6cf3cc9dSRobert Mustacchiexp_pass "mv last -f wins (mv -nif a b)" "$MV -nif" "a b" "a"
506*6cf3cc9dSRobert Mustacchiexp_pass "mv -f always beats -i (non-xpg) (mv -fi a b)" "$MV -fi" "a b" "a"
507*6cf3cc9dSRobert Mustacchiexp_retain "XPG4 mv last -n wins (mv -in a b)" "$XMV -in" "a b"
508*6cf3cc9dSRobert Mustacchiexp_retain "XPG4 mv last -n wins (mv -fn a b)" "$XMV -fn" "a b"
509*6cf3cc9dSRobert Mustacchiexp_retain "XPG4 mv last -n wins (mv -ifn a b)" "$XMV -ifn" "a b"
510*6cf3cc9dSRobert Mustacchiexp_retain "XPG4 mv last -n wins (mv -fifn a b)" "$XMV -fifn" "a b"
511*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv last -f wins (mv -nf a b)" "$XMV -nf" "a b" "a"
512*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv last -f wins (mv -if a b)" "$XMV -if" "a b" "a"
513*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv last -f wins (mv -fif a b)" "$XMV -fif" "a b" "a"
514*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv last -f wins (mv -nif a b)" "$XMV -nif" "a b" "a"
515*6cf3cc9dSRobert Mustacchi
516*6cf3cc9dSRobert Mustacchi
517*6cf3cc9dSRobert Mustacchi#
518*6cf3cc9dSRobert Mustacchi# Now onto interactive tests. Interactivity is a bit challenging. If stdin is
519*6cf3cc9dSRobert Mustacchi# not a tty then a prompt will not appear if we're not in the XPG variant. This
520*6cf3cc9dSRobert Mustacchi# means that it'll fall back to the program default (generally speaking to
521*6cf3cc9dSRobert Mustacchi# overwrite).
522*6cf3cc9dSRobert Mustacchi#
523*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 cp -i no normal file (cp -i a b)" "$XCP -i" "a b" "b" \
524*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
525*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 cp -i yes normal file (cp -i a b)" "$XCP -i" "a b" "a" "yes"
526*6cf3cc9dSRobert Mustacchiexp_pass "cp -i clobbers normal file regardless (cp -i a b)" "$CP -i" "a b" \
527*6cf3cc9dSRobert Mustacchi    "a" "cat /dev/zero"
528*6cf3cc9dSRobert Mustacchi
529*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv -i no normal file (mv -i a b)" "$XMV -i" "a b" "b" \
530*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
531*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv -i yes normal file (mv -i a b)" "$XMV -i" "a b" "a" "yes"
532*6cf3cc9dSRobert Mustacchiexp_pass "mv -i clobbers normal file regardless (mv -i a b)" "$MV -i" "a b" \
533*6cf3cc9dSRobert Mustacchi    "a" "cat /dev/zero"
534*6cf3cc9dSRobert Mustacchi
535*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -i no normal file (ln -i a b)" "$XLN -i" "a b" "b" \
536*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
537*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -i yes normal file (ln -i a b)" "$XLN -i" "a b" "a" "yes"
538*6cf3cc9dSRobert Mustacchiexp_pass "ln -i clobbers normal file regardless (ln -i a b)" "$LN -i" "a b" \
539*6cf3cc9dSRobert Mustacchi    "a" "cat /dev/zero"
540*6cf3cc9dSRobert Mustacchi
541*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 cp -i yes beats -n normal file (cp -ni a b)" "$XCP -ni" "a b" \
542*6cf3cc9dSRobert Mustacchi    "a" "yes"
543*6cf3cc9dSRobert Mustacchiexp_pass "cp -i beats -n (cp -ni a b)" "$CP -ni" "a b" "a" "cat /dev/zero"
544*6cf3cc9dSRobert Mustacchi
545*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv -i beats -n (mv -ni a b)" "$XMV -ni" "a b" "a" "yes"
546*6cf3cc9dSRobert Mustacchiexp_pass "mv -i beats -n (mv -ni a b)" "$MV -ni" "a b" "a" "cat /dev/zero"
547*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 mv -i beats -f (mv -fi a b)" "$XMV -fi" "a b" "a" "yes"
548*6cf3cc9dSRobert Mustacchi
549*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -fi no normal file (ln -fi a b)" "$XLN -fi" "a b" "b" \
550*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
551*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -fi yes normal file (ln -fi a b)" "$XLN -fi" "a b" "a" "yes"
552*6cf3cc9dSRobert Mustacchiexp_pass "ln -fi clobbers normal file regardless (ln -fi a b)" "$LN -fi" \
553*6cf3cc9dSRobert Mustacchi    "a b" "a" "cat /dev/zero"
554*6cf3cc9dSRobert Mustacchi
555*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -sfi no normal file (ln -sfi a b)" "$XLN -sfi" "a b" "b" \
556*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
557*6cf3cc9dSRobert Mustacchiexp_pass "XPG4 ln -sfi yes normal file (ln -sfi a b)" "$XLN -sfi" "a b" "a" \
558*6cf3cc9dSRobert Mustacchi    "yes"
559*6cf3cc9dSRobert Mustacchiexp_pass "ln -sfi clobbers normal file regardless (ln -sfi a b)" "$LN -sfi" \
560*6cf3cc9dSRobert Mustacchi    "a b" "a" "cat /dev/zero"
561*6cf3cc9dSRobert Mustacchi
562*6cf3cc9dSRobert Mustacchi#
563*6cf3cc9dSRobert Mustacchi# Now our last bit here is to do tests that operate on multiple files into a
564*6cf3cc9dSRobert Mustacchi# directory and make sure that they end up as expected.
565*6cf3cc9dSRobert Mustacchi#
566*6cf3cc9dSRobert Mustacchiexp_dir "cp multi-file" "$CP" "a b dir" 0 "dir/a" "b"
567*6cf3cc9dSRobert Mustacchiexp_fail "cp multi-file with socket fails" "$CP" "a b uds dir"
568*6cf3cc9dSRobert Mustacchiexp_fail "cp multi-file with noperms fails" "$CP" "a b c dir"
569*6cf3cc9dSRobert Mustacchiexp_dir "cp multi-file -n" "$CP -n" "a b dir" 0 "dir/a" ""
570*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 cp multi-file -i yes" "$XCP -i" "a b dir" 0 "dir/a" "b" "yes"
571*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 cp multi-file -i no" "$XCP -i" "a b dir" 0 "dir/a" "" \
572*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
573*6cf3cc9dSRobert Mustacchiexp_dir "cp multi-file -i clobbers anyways" "$CP -i" "a b dir" 0 "dir/a" "b" \
574*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
575*6cf3cc9dSRobert Mustacchi
576*6cf3cc9dSRobert Mustacchiexp_dir "ln multi-file" "$LN" "a b dir" 2
577*6cf3cc9dSRobert Mustacchiexp_fail "ln multi-file with door fails" "$LN" "a door dir"
578*6cf3cc9dSRobert Mustacchiexp_dir "ln multi-file with socket works" "$LN" "a uds dir" 0 "dir/a dir/uds" ""
579*6cf3cc9dSRobert Mustacchiexp_dir "ln multi-file with noperms works" "$LN" "a c dir" 0 "dir/a dir/c" ""
580*6cf3cc9dSRobert Mustacchiexp_dir "ln multi-file -f" "$LN -f" "a b dir" 0 "dir/a" "b"
581*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 ln multi-file -i yes" "$XLN -i" "a b dir" 0 "dir/a" "b" "yes"
582*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 ln multi-file -i no" "$XLN -i" "a b dir" 0 "dir/a" "" \
583*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
584*6cf3cc9dSRobert Mustacchiexp_dir "ln multi-file -i clobbers anyways" "$LN -i" "a b dir" 0 "dir/a" "b" \
585*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
586*6cf3cc9dSRobert Mustacchi
587*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file" "$LN -s" "a b dir" 2
588*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file with door works" "$LN -s" "a door dir" 0
589*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file with socket works" "$LN -s" "a uds dir" 0 \
590*6cf3cc9dSRobert Mustacchi    "dir/a dir/uds" ""
591*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file with noperms works" "$LN -s" "a c dir" 0 \
592*6cf3cc9dSRobert Mustacchi    "dir/a dir/c" ""
593*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file -f" "$LN -s -f" "a b dir" 0 "dir/a" "b"
594*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 ln -s multi-file -i yes" "$XLN -s -i" "a b dir" 0 "dir/a" "b" \
595*6cf3cc9dSRobert Mustacchi    "yes"
596*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 ln -s multi-file -i no" "$XLN -s -i" "a b dir" 0 "dir/a" "" \
597*6cf3cc9dSRobert Mustacchi    "cat /dev/zero"
598*6cf3cc9dSRobert Mustacchiexp_dir "ln -s multi-file -i clobbers anyways" "$LN -s -i" "a b dir" 0 "dir/a" \
599*6cf3cc9dSRobert Mustacchi    "b" "cat /dev/zero"
600*6cf3cc9dSRobert Mustacchi
601*6cf3cc9dSRobert Mustacchiexp_dir "mv multi-file" "$MV" "a b c fifo door uds symlink dangle dir" 0 \
602*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" "b"
603*6cf3cc9dSRobert Mustacchiexp_dir "mv -n multi-file" "$MV -n" "a b c fifo door uds symlink dangle dir" 0 \
604*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" ""
605*6cf3cc9dSRobert Mustacchiexp_dir "mv -f multi-file" "$MV -f" "a b c fifo door uds symlink dangle dir" 0 \
606*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" "b"
607*6cf3cc9dSRobert Mustacchiexp_dir "mv -i multi-file clobbers" "$MV -i" \
608*6cf3cc9dSRobert Mustacchi    "a b c fifo door uds symlink dangle dir" 0 \
609*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" "b" \
610*6cf3cc9dSRobert Mustacchi    "cat /dev/null"
611*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 mv -i multi-file no" "$XMV -i" \
612*6cf3cc9dSRobert Mustacchi    "a b c fifo door uds symlink dangle dir" 0 \
613*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" "" \
614*6cf3cc9dSRobert Mustacchi    "cat /dev/null"
615*6cf3cc9dSRobert Mustacchiexp_dir "XPG4 mv -i multi-file yes" "$XMV -i" \
616*6cf3cc9dSRobert Mustacchi    "a b c fifo door uds symlink dangle dir" 0 \
617*6cf3cc9dSRobert Mustacchi    "dir/a dir/c dir/fifo dir/door dir/uds dir/symlink dir/dangle" "b" "yes"
618*6cf3cc9dSRobert Mustacchi
619*6cf3cc9dSRobert Mustacchiif (( ovr_exit == 0 )); then
620*6cf3cc9dSRobert Mustacchi	printf "All tests passed successfully\n"
621*6cf3cc9dSRobert Mustacchifi
622*6cf3cc9dSRobert Mustacchiexit $ovr_exit
623