1From e8b56ebd536e82b15542a00c888109471936bfda Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
3Date: Fri, 24 Sep 2021 20:57:41 +0100
4Subject: [PATCH] chmod: fix exit status when ignoring symlinks
5
6* src/chmod.c: Reorder enum so CH_NOT_APPLIED
7can be treated as a non error.
8* tests/chmod/ignore-symlink.sh: A new test.
9* tests/local.mk: Reference the new test.
10* NEWS: Mention the bug fix.
11Fixes https://bugs.gnu.org/50784
12---
13 NEWS | 6 ++++++
14 src/chmod.c | 4 ++--
15 tests/chmod/ignore-symlink.sh | 31 +++++++++++++++++++++++++++++++
16 tests/local.mk | 1 +
17 4 files changed, 40 insertions(+), 2 deletions(-)
18 create mode 100755 tests/chmod/ignore-symlink.sh
19
20diff --git a/NEWS b/NEWS
21index a1470a7d7..1cb3c28a1 100644
22--- a/NEWS
23+++ b/NEWS
24@@ -2,6 +2,12 @@ GNU coreutils NEWS -*- outline -*-
25
26 * Noteworthy changes in release ?.? (????-??-??) [?]
27
28+** Bug fixes
29+
30+ chmod -R no longer exits with error status when encountering symlinks.
31+ All files would be processed correctly, but the exit status was incorrect.
32+ [bug introduced in coreutils-9.0]
33+
34
35 * Noteworthy changes in release 9.0 (2021-09-24) [stable]
36
37diff --git a/src/chmod.c b/src/chmod.c
38index 37b04f500..57ac47f33 100644
39--- a/src/chmod.c
40+++ b/src/chmod.c
41@@ -44,8 +44,8 @@ struct change_status
42 enum
43 {
44 CH_NO_STAT,
45- CH_NOT_APPLIED,
46 CH_FAILED,
47+ CH_NOT_APPLIED,
48 CH_NO_CHANGE_REQUESTED,
49 CH_SUCCEEDED
50 }
51@@ -322,7 +322,7 @@ process_file (FTS *fts, FTSENT *ent)
52 if ( ! recurse)
53 fts_set (fts, ent, FTS_SKIP);
54
55- return CH_NO_CHANGE_REQUESTED <= ch.status;
56+ return CH_NOT_APPLIED <= ch.status;
57 }
58
59 /* Recursively change the modes of the specified FILES (the last entry
60diff --git a/tests/chmod/ignore-symlink.sh b/tests/chmod/ignore-symlink.sh
61new file mode 100755
62index 000000000..5ce3de816
63--- /dev/null
64+++ b/tests/chmod/ignore-symlink.sh
65@@ -0,0 +1,31 @@
66+#!/bin/sh
67+# Test for proper exit code of chmod on a processed symlink.
68+
69+# Copyright (C) 2021 Free Software Foundation, Inc.
70+
71+# This program is free software: you can redistribute it and/or modify
72+# it under the terms of the GNU General Public License as published by
73+# the Free Software Foundation, either version 3 of the License, or
74+# (at your option) any later version.
75+
76+# This program is distributed in the hope that it will be useful,
77+# but WITHOUT ANY WARRANTY; without even the implied warranty of
78+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79+# GNU General Public License for more details.
80+
81+# You should have received a copy of the GNU General Public License
82+# along with this program. If not, see <https://www.gnu.org/licenses/>.
83+
84+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
85+print_ver_ chmod
86+
87+mkdir dir || framework_failure_
88+touch dir/f || framework_failure_
89+ln -s f dir/l || framework_failure_
90+
91+# This operation ignores symlinks but should succeed.
92+chmod u+w -R dir 2> out || fail=1
93+
94+compare /dev/null out || fail=1
95+
96+Exit $fail
97diff --git a/tests/local.mk b/tests/local.mk
98index 228d0e368..b5b893fb7 100644
99--- a/tests/local.mk
100+++ b/tests/local.mk
101@@ -456,6 +456,7 @@ all_tests = \
102 tests/chmod/c-option.sh \
103 tests/chmod/equal-x.sh \
104 tests/chmod/equals.sh \
105+ tests/chmod/ignore-symlink.sh \
106 tests/chmod/inaccessible.sh \
107 tests/chmod/octal.sh \
108 tests/chmod/setgid.sh \