1#!/bin/sh
2# Ensure that using 'cp --preserve=link' to copy hard-linked arguments
3# onto existing destinations works, even when one of the link operations fails.
4
5# Copyright (C) 2003-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
21# This bug was fixed in coreutils-4.5.9.
22# To exercise this bug is non-trivial:
23# Set-up requires at least three hard-linked files.  In copying them,
24# while preserving links, the initial copy must succeed, the attempt
25# to create the second file via 'link' must fail, and the final 'link'
26# (to create the third) must succeed.  Before the corresponding fix,
27# the first and third destination files would not be linked.
28#
29# Note that this is nominally a test of 'cp', yet it is in the tests/mv
30# directory, because it requires use of the --preserve=link option that
31# mv enables by default.
32
33. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
34print_ver_ cp
35skip_if_root_
36
37mkdir -p x dst/x || framework_failure_
38touch dst/x/b || framework_failure_
39chmod a-w dst/x
40touch a || framework_failure_
41ln a x/b || framework_failure_
42ln a c || framework_failure_
43
44
45# ======================================
46# This must fail -- because x/b cannot be unlinked.
47cp --preserve=link --parents a x/b c dst 2> /dev/null && fail=1
48
49# Source files must remain.
50test -f a || fail=1
51test -f x/b || fail=1
52test -f c || fail=1
53cd dst
54
55# Three destination files must exist.
56test -f a || fail=1
57test -f x/b || fail=1
58test -f c || fail=1
59
60# The i-node numbers of a and c must be the same.
61ia=$(ls -i a) || fail=1; set x $ia; ia=$2
62ic=$(ls -i c) || fail=1; set x $ic; ic=$2
63test "$ia" = "$ic" || fail=1
64
65# The i-node number of x/b must be different.
66ib=$(ls -i x/b) || fail=1; set x $ib; ib=$2
67test "$ia" = "$ib" && fail=1
68
69Exit $fail
70