81 lines
3.2 KiB
Diff
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
|
|
|