find: Fall back from stat() to lstat() on broken links - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit e861343db1d13e1e7497e81db56526fd5505704b
 (DIR) parent eb749d1c88c0557ed06733de89efda1e252facc2
 (HTM) Author: Tavian Barnes <tavianator@tavianator.com>
       Date:   Sat, 22 Feb 2025 13:14:47 +0100
       
       find: Fall back from stat() to lstat() on broken links
       
       Diffstat:
         M find.c                              |      19 +++++++++++++++++--
       
       1 file changed, 17 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/find.c b/find.c
       @@ -112,6 +112,7 @@ struct findhist {
        
        /* Utility */
        static int spawn(char *argv[]);
       +static int do_stat(char *path, struct stat *sb, struct findhist *hist);
        
        /* Primaries */
        static int pri_name   (struct arg *arg);
       @@ -254,6 +255,20 @@ spawn(char *argv[])
                return status;
        }
        
       +static int
       +do_stat(char *path, struct stat *sb, struct findhist *hist)
       +{
       +        if (gflags.l || (gflags.h && !hist)) {
       +                if (stat(path, sb) == 0) {
       +                        return 0;
       +                } else if (errno != ENOENT && errno != ENOTDIR) {
       +                        return -1;
       +                }
       +        }
       +
       +        return lstat(path, sb);
       +}
       +
        /*
         * Primaries
         */
       @@ -664,7 +679,7 @@ get_newer_arg(char *argv[], union extra *extra)
        {
                struct stat st;
        
       -        if (stat(*argv, &st))
       +        if (do_stat(*argv, &st, NULL))
                        eprintf("failed to stat '%s':", *argv);
        
                extra->i = st.st_mtime;
       @@ -943,7 +958,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 (do_stat(path, &st, hist) < 0) {
                        weprintf("failed to stat %s:", path);
                        return;
                }