From 74c1f309e35d456c48efed5d2193df4f66b67272 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 2 Nov 2014 22:11:34 -0800 Subject: grep: port O_NOFOLLOW errno checking to NetBSD Problem reported by Assaf Gordon in: http://bugs.gnu.org/18892 * NEWS: Document it. * src/grep.c (open_symlink_nofollow_error): New function, which does the right thing on NetBSD. (grepfile): Use it. --- NEWS | 4 ++++ src/grep.c | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 183b7f0b..c4651627 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,10 @@ GNU grep NEWS -*- outline -*- grep -E rejected unmatched ')', instead of treating it like '\)'. [bug present since "the beginning"] + On NetBSD, grep -r no longer reports "Inappropriate file type or format" + when refusing to follow a symbolic link. + [bug introduced in grep-2.12] + ** Changes in behavior The GREP_OPTIONS environment variable is now obsolescent, and grep diff --git a/src/grep.c b/src/grep.c index 0a4ac277..8dbf86ec 100644 --- a/src/grep.c +++ b/src/grep.c @@ -1513,13 +1513,27 @@ grepdirent (FTS *fts, FTSENT *ent, bool command_line) return grepfile (dirdesc, ent->fts_accpath, follow, command_line); } +/* True if errno is ERR after 'open ("symlink", ... O_NOFOLLOW ...)'. + POSIX specifies ELOOP, but it's EMLINK on FreeBSD and EFTYPE on NetBSD. */ +static bool +open_symlink_nofollow_error (int err) +{ + if (err == ELOOP || err == EMLINK) + return true; +#ifdef EFTYPE + if (err == EFTYPE) + return true; +#endif + return false; +} + static bool 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)) + if (follow || ! open_symlink_nofollow_error (errno)) suppressible_error (filename, errno); return true; } -- cgit v1.2.1