Assaf Gordon <assafgor...@gmail.com> wrote:
> On 11/01/2014 10:39 PM, Paul Eggert wrote:
> > Assaf Gordon wrote:
> 
> >> $ ../../../src/grep -r '^' ; echo $?
> >> a:a
> >> b:b
> >> ../../../src/grep: c: Inappropriate file type or format
> >> ../../../src/grep: d: Inappropriate file type or format
> >> ../../../src/grep: e: Inappropriate file type or format
> >> 2
> >
> > What system calls is this 'grep' executing?  What's the output of ktrace 
> > and kdump?
> 
> Attached is the ktrace+tdump output of running the command.
> 
> The error appears on line 217 (open() returns -1 for file "c"),
> though similar errors stemming from 'fstat' for files a,b are ignored (lines 
> 150,191).
> 
> - Assaf

NetBSD returns errno == EFTYPE in open with O_NOFOLLOW for symlink
instead of errno == ELOOP which POSIX says.  Similarly, Tru64 returns
errno == ENOTSUP.  So I added them to ignorable list.
From 163e4e868fce733c494e6d3154e6adf97c64de9c Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <nori...@kcn.ne.jp>
Date: Mon, 3 Nov 2014 14:04:40 +0900
Subject: [PATCH] grep: fix symlink non-conforming to POSIX

Reported by Assaf Gordon in: http://bugs.gnu.org/18892
* src/grep.c (grepfile): Also treat EFTYPE (if defined) and ENOTSUP
as ELOOP.
---
 src/grep.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/grep.c b/src/grep.c
index 0a4ac27..559c623 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -1519,8 +1519,26 @@ grepfile (int dirdesc, char const *name, bool follow, 
bool command_line)
   int desc = openat_safer (dirdesc, name, O_RDONLY | (follow ? 0 : 
O_NOFOLLOW));
   if (desc < 0)
     {
-      if (follow || (errno != ELOOP && errno != EMLINK))
-        suppressible_error (filename, errno);
+      if (!follow)
+        switch (errno)
+          {
+          case ELOOP:
+
+            /* With open ("symlink", O_NOFOLLOW|...), POSIX says
+               errno == ELOOP, but some operating systems do not conform
+               to the standard.  */
+#ifdef EFTYPE
+            /* NetBSD uses errno == EFTYPE.  */
+          case EFTYPE:
+#endif
+            /* FreeBSD 8.1 uses errno == EMLINK.  */
+          case EMLINK:
+
+            /* Tru64 5.1B uses errno == ENOTSUP.  */
+          case ENOTSUP:
+            return true;
+          }
+      suppressible_error (filename, errno);
       return true;
     }
   return grepdesc (desc, command_line);
-- 
2.1.3

Reply via email to