From 9e408d4bb50cb7c4e9d0a007b95f9fb9d32a16d0 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Mon, 3 Jun 2024 18:30:09 -0400
Subject: Make ELOOP an error again, except for -xtype.

POSIX requires an error if (for example) -L encounters a symlink loop.
The GNU find change was restricted to -xtype, so add a manual ELOOP test
to eval_xtype() for compatibility.

This reverts commit 470589cbd9ca3e73d8c01ac3a96cbc065179dcc5.

Link: https://savannah.gnu.org/bugs/?19605
---
 src/bfstd.c | 2 +-
 src/eval.c  | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/bfstd.c b/src/bfstd.c
index 1c5e289..44eda7c 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -44,7 +44,7 @@ bool error_is_like(int error, int category) {
 
 	switch (category) {
 	case ENOENT:
-		return error == ENOTDIR || error == ELOOP;
+		return error == ENOTDIR;
 
 	case ENOSYS:
 		// https://github.com/opencontainers/runc/issues/2151
diff --git a/src/eval.c b/src/eval.c
index 0495207..cef766d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -999,6 +999,13 @@ bool eval_xtype(const struct bfs_expr *expr, struct bfs_eval *state) {
 	const struct BFTW *ftwbuf = state->ftwbuf;
 	enum bfs_stat_flags flags = ftwbuf->stat_flags ^ (BFS_STAT_NOFOLLOW | BFS_STAT_TRYFOLLOW);
 	enum bfs_type type = bftw_type(ftwbuf, flags);
+
+	// GNU find treats ELOOP as a broken symbolic link for -xtype l
+	// (but not -L -type l)
+	if ((flags & BFS_STAT_TRYFOLLOW) && type == BFS_ERROR && errno == ELOOP) {
+		type = BFS_LNK;
+	}
+
 	if (type == BFS_ERROR) {
 		eval_report_error(state);
 		return false;
-- 
cgit v1.2.3