From: Tavian Barnes <taviana...@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 @@ -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 */ @@ -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; @@ -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