[dev] [PATCH 2/2] find: Use the symlink itself for broken symlinks

From: <tavianator_AT_tavianator.com>
Date: Thu, 1 Nov 2018 22:05:17 -0400

From: Tavian Barnes <tavianator_AT_tavianator.com>

About -H/-L, POSIX says

> If the referenced file does not exist, the file information and type
> shall be for the link itself.

so we need to fall back from stat() to lstat() if errno indicates a
broken link.
---
 find.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/find.c b/find.c
index f96c05b..d907594 100644
--- a/find.c
+++ b/find.c
_AT_@ -223,6 +223,19 @@ static struct {
 	char print; /* whether we will need -print when parsing           */
 } gflags;
 
+static int
+find_stat(const char *path, int is_root, struct stat *st)
+{
+	if (gflags.l || (gflags.h && is_root)) {
+		int ret = stat(path, st);
+		if (ret == 0 || (errno != ENOENT && errno != ENOTDIR)) {
+			return ret;
+		}
+	}
+
+	return lstat(path, st);
+}
+
 /*
  * Primaries
  */
_AT_@ -660,7 +673,7 @@ get_newer_arg(char *argv[], union extra *extra)
 {
 	struct stat st;
 
-	if (stat(*argv, &st))
+	if (find_stat(*argv, 1, &st))
 		eprintf("failed to stat '%s':", *argv);
 
 	extra->i = st.st_mtime;
_AT_@ -944,7 +957,7 @@ find(char *path, struct findhist *hist)
 
 	len = strlen(path) + 2; /* \0 and '/' */
 
-	if ((gflags.l || (gflags.h && !hist) ? stat(path, &st) : lstat(path, &st)) < 0) {
+	if (find_stat(path, !hist, &st) < 0) {
 		weprintf("failed to stat %s:", path);
 		return;
 	}
-- 
2.19.1
Received on Fri Nov 02 2018 - 03:05:17 CET

This archive was generated by hypermail 2.3.0 : Fri Nov 02 2018 - 03:12:07 CET