]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hardlink: handle ENOTDIR from nftw() on a file
authorThomas Weißschuh <thomas@t-8ch.de>
Sun, 12 Apr 2026 06:09:32 +0000 (08:09 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Tue, 28 Apr 2026 08:31:52 +0000 (10:31 +0200)
POSIX allows nftw() to return ENOTDIR if the path argument does not
point to a directory. This happens for example on macOS.

Handle ENOTDIR by calling the existing handler manually on the single
file.

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
misc-utils/hardlink.c

index f687f873c2548c0b3be8feebbb96b548f987da64..d7e9ade5af877999b8ce2d8db9ed6e8978187564 100644 (file)
@@ -958,6 +958,25 @@ static int inserter(const char *fpath, const struct stat *sb,
        return 0;
 }
 
+static int insert_file(const char *fpath)
+{
+       struct FTW ftw = {};
+       const char *base;
+       struct stat sb;
+       int rc;
+
+       rc = stat(fpath, &sb);
+       if (rc == -1) {
+               warn(_("cannot stat %s"), fpath);
+               return 0;
+       }
+
+       base = strrchr(fpath, '/');
+       ftw.base = base ? base - fpath + 1: 0;
+
+       return inserter(fpath, &sb, FTW_F, &ftw);
+}
+
 #ifdef USE_REFLINK
 static int is_reflink_compatible(dev_t devno, const char *filename)
 {
@@ -1522,8 +1541,10 @@ int main(int argc, char *argv[])
                if (opts.prio_trees)
                        ++curr_tree;
 
-               if (nftw(path, inserter, 20, ftw_flags) == -1)
-                       warn(_("cannot process %s"), path);
+               if (nftw(path, inserter, 20, ftw_flags) == -1) {
+                       if (errno != ENOTDIR || insert_file(path) != 0)
+                               warn(_("cannot process %s"), path);
+               }
 
                free(path);
                rootbasesz = 0;