From: Thomas Weißschuh Date: Sun, 12 Apr 2026 06:09:32 +0000 (+0200) Subject: hardlink: handle ENOTDIR from nftw() on a file X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=8429fa8b5094abf7dc8ca4fe18d35606043fa907;p=thirdparty%2Futil-linux.git hardlink: handle ENOTDIR from nftw() on a file 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 --- diff --git a/misc-utils/hardlink.c b/misc-utils/hardlink.c index f687f873c..d7e9ade5a 100644 --- a/misc-utils/hardlink.c +++ b/misc-utils/hardlink.c @@ -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;