findutils/find-fix-printf-Y-output-to-N-for-broken-links.patch
2019-09-30 10:38:48 -04:00

81 lines
3.2 KiB
Diff

From 7b7a19c95f236cd18f48e44b7cc6794d21c0369f Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <mail@bernhard-voelker.de>
Date: Fri, 20 Jul 2018 10:07:13 +0200
Subject: [PATCH 181/224] find: fix -printf %Y output to 'N' for broken links
The format %Y shall output 'N' for broken links (ENOENT), 'L' for ELOOP,
and '?' for any other error when stat()ing the symlink target.
The %Y implementation implicitly fell back to lstat(); therefore it
output 'l' for dangling symlinks.
$ ln -s ENOENT DANGLE
$ find -D stat DANGLE -printf '%y %Y %p\n'
fallback_stat(): stat(DANGLE) failed; falling back on lstat()
l l DANGLE
* find/print.c (do_fprintf): For %Y, always follow links to determine
the type of the symlink target.
* find/testsuite/find.gnu/printf-symlink.exp: Add a test case for broken
links and the ELOOP case ...
* find/testsuite/find.gnu/printf-symlink.xo: ... with the expected output.
* NEWS (Bug fixes): Mention the fix.
Bug introduced in version v4.5.8 with commit '25e7c5fbf9'.
---
NEWS | 4 ++++
find/print.c | 9 +++++----
find/testsuite/find.gnu/printf-symlink.exp | 5 ++++-
find/testsuite/find.gnu/printf-symlink.xo | 4 ++++
4 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/find/print.c b/find/print.c
index 3af3e91d..545df96a 100644
--- a/find/print.c
+++ b/find/print.c
@@ -1175,11 +1175,12 @@ do_fprintf (struct format_val *dest,
if (S_ISLNK (stat_buf->st_mode))
{
struct stat sbuf;
- /* If we would normally follow links, do not do so.
- * If we would normally not follow links, do so.
+ /* %Y needs to stat the symlink target regardless of
+ * whether we would normally follow symbolic links or not.
+ * (Actually we do not even come here when following_links()
+ * other than the ENOENT case.)
*/
- if ((following_links () ? optionp_stat : optionl_stat)
- (state.rel_pathname, &sbuf) != 0)
+ if (fstatat (state.cwd_dir_fd, state.rel_pathname, &sbuf, 0) != 0)
{
if ( errno == ENOENT )
{
diff --git a/find/testsuite/find.gnu/printf-symlink.exp b/find/testsuite/find.gnu/printf-symlink.exp
index 6acc3e68..453f07fc 100644
--- a/find/testsuite/find.gnu/printf-symlink.exp
+++ b/find/testsuite/find.gnu/printf-symlink.exp
@@ -2,5 +2,8 @@ exec rm -rf tmp
exec mkdir tmp
exec touch tmp/file
exec ln -s file tmp/LINK
-find_start p {tmp/LINK -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
+exec ln -s ENOENT tmp/DANGLE
+exec ln -s SELF tmp/SELF
+exec ls -ls tmp
+find_start p {tmp/LINK tmp/DANGLE tmp/SELF -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
exec rm -rf tmp
diff --git a/find/testsuite/find.gnu/printf-symlink.xo b/find/testsuite/find.gnu/printf-symlink.xo
index cc2b69c4..08eb83c6 100644
--- a/find/testsuite/find.gnu/printf-symlink.xo
+++ b/find/testsuite/find.gnu/printf-symlink.xo
@@ -1,2 +1,6 @@
RESULT: l f tmp/LINK
RESULT2: f l tmp/LINK
+RESULT: l N tmp/DANGLE
+RESULT2: N l tmp/DANGLE
+RESULT: l L tmp/SELF
+RESULT2: L l tmp/SELF
--
2.19.1