1#!/bin/sh 2# make sure cp and mv can handle many combinations of local and 3# other-partition regular/symlink'd files. 4 5# Copyright (C) 2000-2023 Free Software Foundation, Inc. 6 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <https://www.gnu.org/licenses/>. 19 20. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 21print_ver_ cp mv 22 23cleanup_() { rm -rf "$other_partition_tmpdir"; } 24. "$abs_srcdir/tests/other-fs-tmpdir" 25 26# On NFS on Linux 2.6.9 at least we get: 27# mv: preserving permissions for 'rem_sl': Operation not supported 28require_local_dir_ 29 30pwd_tmp=$(pwd) 31 32# Unset CDPATH. Otherwise, output from the 'cd dir' command 33# can make this test fail. 34(unset CDPATH) >/dev/null 2>&1 && unset CDPATH 35 36 37# Four cases: 38# local regular file w/symlink on another partition 39# (loc_reg, rem_sl) 40# (rem_sl, loc_reg) 41# local symlink to regular file on another partition 42# (loc_sl, rem_reg) 43# (rem_reg, loc_sl) 44 45# Exercise those four cases for each of 46# cp and mv, with lots of combinations of options. 47 48exec 1> actual 49 50# FIXME: This should be bigger: like more than 8k 51contents=XYZ 52 53loc_reg=loc_reg 54loc_sl=loc_sl 55rem_reg=$other_partition_tmpdir/rem_reg 56rem_sl=$other_partition_tmpdir/rem_sl 57 58for copy in cp mv; do 59 for args in \ 60 'loc_reg rem_sl' \ 61 'rem_sl loc_reg' \ 62 'loc_sl rem_reg' \ 63 'rem_reg loc_sl' \ 64 ; do 65 for options in '' --rem '--rem -d' '--rem -b' -b -bd -d; do 66 case "$options" in *d*|*--rem*) test $copy = mv && continue;; esac 67 rm -rf dir || fail=1 68 rm -f "$other_partition_tmpdir"/* || fail=1 69 mkdir dir || fail=1 70 cd dir || fail=1 71 case "$args" in *loc_reg*) reg_abs="$(pwd)/$loc_reg" ;; esac 72 case "$args" in *rem_reg*) reg_abs=$rem_reg ;; esac 73 case "$args" in *loc_sl*) slink=$loc_sl ;; esac 74 case "$args" in *rem_sl*) slink=$rem_sl ;; esac 75 76 echo $contents > "$reg_abs" || framework_failure_ 77 ln -nsf "$reg_abs" $slink || fail=1 78 actual_args=$(echo $args|sed 's,^,$,;s/ / $/') 79 actual_args=$(eval echo $actual_args) 80 81 ( 82 ( 83 # echo 1>&2 cp $options $args 84 $copy $options $actual_args 2>.err 85 copy_status=$? 86 echo $copy_status $copy $options $args 87 88 # Normalize the program name in the error output, 89 # remove any site-dependent part of other-partition file name, 90 # and put brackets around the output. 91 test -s .err \ 92 && { 93 echo ' [' | tr -d '\n' 94 sed 's/^[^:][^:]*\(..\):/\1:/;s,'"$other_partition_tmpdir/,," .err | 95 tr -d '\n' 96 echo ']' 97 } 98 # Strip off all but the file names. 99 # Remove any site-dependent part of each file name. 100 ls=$(ls -gG --ignore=.err . \ 101 | sed \ 102 -e '/^total /d' \ 103 -e "s,$other_partition_tmpdir/,," \ 104 -e "s,$pwd_tmp/,," \ 105 -e 's/^[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *//') 106 ls2=$(cd "$other_partition_tmpdir" && ls -gG --ignore=.err . \ 107 | sed \ 108 -e '/^total /d' \ 109 -e "s,$other_partition_tmpdir/,," \ 110 -e "s,$pwd_tmp/,," \ 111 -e 's/^[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *//') 112 echo " ("$ls") ("$ls2")" 113 114 # If the command failed, then it must not have changed the files. 115 if test $copy_status != 0; then 116 for f in $actual_args; do 117 test -f $f || 118 { echo " $copy FAILED but removed $f"; continue; } 119 case "$(cat $f)" in 120 "$contents") ;; 121 *) echo " $copy FAILED but modified $f";; 122 esac 123 done 124 fi 125 126 if test $copy = cp; then 127 # Make sure the original is unchanged and that 128 # the destination is a copy. 129 for f in $actual_args; do 130 if test -f $f; then 131 if test $copy_status != 0; then 132 test 133 fi 134 case "$(cat $f)" in 135 "$contents") ;; 136 *) echo " $copy FAILED";; 137 esac 138 else 139 echo " symlink-loop" 140 fi 141 done 142 fi 143 ) 144 ) | sed 's/ *$//' 145 cd .. 146 done 147 echo 148 done 149done 150 151test $fail = 1 && 152 { (exit 1); exit; } 153 154cat <<\EOF > expected || framework_failure_ 1551 cp loc_reg rem_sl 156 [cp: 'loc_reg' and 'rem_sl' are the same file] 157 (loc_reg) (rem_sl -> dir/loc_reg) 1580 cp --rem loc_reg rem_sl 159 (loc_reg) (rem_sl) 1600 cp --rem -d loc_reg rem_sl 161 (loc_reg) (rem_sl) 1620 cp --rem -b loc_reg rem_sl 163 (loc_reg) (rem_sl rem_sl~ -> dir/loc_reg) 1640 cp -b loc_reg rem_sl 165 (loc_reg) (rem_sl rem_sl~ -> dir/loc_reg) 1660 cp -bd loc_reg rem_sl 167 (loc_reg) (rem_sl rem_sl~ -> dir/loc_reg) 1681 cp -d loc_reg rem_sl 169 [cp: 'loc_reg' and 'rem_sl' are the same file] 170 (loc_reg) (rem_sl -> dir/loc_reg) 171 1721 cp rem_sl loc_reg 173 [cp: 'rem_sl' and 'loc_reg' are the same file] 174 (loc_reg) (rem_sl -> dir/loc_reg) 1751 cp --rem rem_sl loc_reg 176 [cp: 'rem_sl' and 'loc_reg' are the same file] 177 (loc_reg) (rem_sl -> dir/loc_reg) 1781 cp --rem -d rem_sl loc_reg 179 [cp: 'rem_sl' and 'loc_reg' are the same file] 180 (loc_reg) (rem_sl -> dir/loc_reg) 1811 cp --rem -b rem_sl loc_reg 182 [cp: 'rem_sl' and 'loc_reg' are the same file] 183 (loc_reg) (rem_sl -> dir/loc_reg) 1841 cp -b rem_sl loc_reg 185 [cp: 'rem_sl' and 'loc_reg' are the same file] 186 (loc_reg) (rem_sl -> dir/loc_reg) 1870 cp -bd rem_sl loc_reg 188 (loc_reg -> dir/loc_reg loc_reg~) (rem_sl -> dir/loc_reg) 189 symlink-loop 190 symlink-loop 1911 cp -d rem_sl loc_reg 192 [cp: 'rem_sl' and 'loc_reg' are the same file] 193 (loc_reg) (rem_sl -> dir/loc_reg) 194 1951 cp loc_sl rem_reg 196 [cp: 'loc_sl' and 'rem_reg' are the same file] 197 (loc_sl -> rem_reg) (rem_reg) 1981 cp --rem loc_sl rem_reg 199 [cp: 'loc_sl' and 'rem_reg' are the same file] 200 (loc_sl -> rem_reg) (rem_reg) 2011 cp --rem -d loc_sl rem_reg 202 [cp: 'loc_sl' and 'rem_reg' are the same file] 203 (loc_sl -> rem_reg) (rem_reg) 2041 cp --rem -b loc_sl rem_reg 205 [cp: 'loc_sl' and 'rem_reg' are the same file] 206 (loc_sl -> rem_reg) (rem_reg) 2071 cp -b loc_sl rem_reg 208 [cp: 'loc_sl' and 'rem_reg' are the same file] 209 (loc_sl -> rem_reg) (rem_reg) 2100 cp -bd loc_sl rem_reg 211 (loc_sl -> rem_reg) (rem_reg -> rem_reg rem_reg~) 212 symlink-loop 213 symlink-loop 2141 cp -d loc_sl rem_reg 215 [cp: 'loc_sl' and 'rem_reg' are the same file] 216 (loc_sl -> rem_reg) (rem_reg) 217 2181 cp rem_reg loc_sl 219 [cp: 'rem_reg' and 'loc_sl' are the same file] 220 (loc_sl -> rem_reg) (rem_reg) 2210 cp --rem rem_reg loc_sl 222 (loc_sl) (rem_reg) 2230 cp --rem -d rem_reg loc_sl 224 (loc_sl) (rem_reg) 2250 cp --rem -b rem_reg loc_sl 226 (loc_sl loc_sl~ -> rem_reg) (rem_reg) 2270 cp -b rem_reg loc_sl 228 (loc_sl loc_sl~ -> rem_reg) (rem_reg) 2290 cp -bd rem_reg loc_sl 230 (loc_sl loc_sl~ -> rem_reg) (rem_reg) 2311 cp -d rem_reg loc_sl 232 [cp: 'rem_reg' and 'loc_sl' are the same file] 233 (loc_sl -> rem_reg) (rem_reg) 234 2350 mv loc_reg rem_sl 236 () (rem_sl) 2370 mv -b loc_reg rem_sl 238 () (rem_sl rem_sl~ -> dir/loc_reg) 239 2401 mv rem_sl loc_reg 241 [mv: 'rem_sl' and 'loc_reg' are the same file] 242 (loc_reg) (rem_sl -> dir/loc_reg) 2430 mv -b rem_sl loc_reg 244 (loc_reg -> dir/loc_reg loc_reg~) () 245 2461 mv loc_sl rem_reg 247 [mv: 'loc_sl' and 'rem_reg' are the same file] 248 (loc_sl -> rem_reg) (rem_reg) 2490 mv -b loc_sl rem_reg 250 () (rem_reg -> rem_reg rem_reg~) 251 2520 mv rem_reg loc_sl 253 (loc_sl) () 2540 mv -b rem_reg loc_sl 255 (loc_sl loc_sl~ -> rem_reg) () 256 257EOF 258 259# Redirect to stderr, since stdout is already taken. 260compare expected actual 1>&2 || fail=1 261 262Exit $fail 263