From ba6be2889642010c8f30affe403981aa2cc39631 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <mail@bernhard-voelker.de>
Date: Tue, 24 Jul 2018 08:34:38 +0200
Subject: [PATCH 184/224] find -printf %Y: handle ENOTDIR also as broken
 symlink

The above command should output 'N' (for broken symlinks) not only in
the ENOENT case, but also when an intermediate part of the symlink target
file name is a file (ENOTDIR):

  $ touch file
  $ ln -s file/ENOTDIR link
  $ find link -printf '%Y %p\n'
  N link

Previously, find output 'l' as for a resolvable symlink.

* find/print.c (do_fprintf): Treat ENOTDIR the same as ENOENT to detect
broken symlinks.
* find/testsuite/find.gnu/printf-symlink.exp: Extend the test, and ...
* find/testsuite/find.gnu/printf-symlink.xo: ... the expected output.
* NEWS (Bug fixes, #54262): Explicitly mention that both ENOENT and ENOTDIR
are used to detect broken symlinks.

Suggested by Tavian Barnes.
---
 NEWS                                       | 4 ++--
 find/print.c                               | 2 +-
 find/testsuite/find.gnu/printf-symlink.exp | 3 ++-
 find/testsuite/find.gnu/printf-symlink.xo  | 2 ++
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/find/print.c b/find/print.c
index 24bd9692..1bfccbfc 100644
--- a/find/print.c
+++ b/find/print.c
@@ -1182,7 +1182,7 @@ do_fprintf (struct format_val *dest,
                  */
                 if (fstatat (state.cwd_dir_fd, state.rel_pathname, &sbuf, 0) != 0)
                   {
-                    if ( errno == ENOENT )
+                    if ( (errno == ENOENT) || (errno == ENOTDIR) )
                       {
                         checked_fprintf (dest, segment->text, "N");
                         break;
diff --git a/find/testsuite/find.gnu/printf-symlink.exp b/find/testsuite/find.gnu/printf-symlink.exp
index 453f07fc..077f18b5 100644
--- a/find/testsuite/find.gnu/printf-symlink.exp
+++ b/find/testsuite/find.gnu/printf-symlink.exp
@@ -3,7 +3,8 @@ exec mkdir tmp
 exec touch tmp/file
 exec ln -s file tmp/LINK
 exec ln -s ENOENT tmp/DANGLE
+exec ln -s file/ENOTDIR tmp/ENOTDIR
 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" }
+find_start p {tmp/LINK tmp/DANGLE tmp/ENOTDIR 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 08eb83c6..978c6673 100644
--- a/find/testsuite/find.gnu/printf-symlink.xo
+++ b/find/testsuite/find.gnu/printf-symlink.xo
@@ -2,5 +2,7 @@ RESULT: l f tmp/LINK
 RESULT2: f l tmp/LINK
 RESULT: l N tmp/DANGLE
 RESULT2: N l tmp/DANGLE
+RESULT: l N tmp/ENOTDIR
+RESULT2: N l tmp/ENOTDIR
 RESULT: l L tmp/SELF
 RESULT2: L l tmp/SELF
-- 
2.19.1

