diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1 index cffeacf7ef5..1abe8251fac 100644 --- a/usr.bin/find/find.1 +++ b/usr.bin/find/find.1 @@ -31,7 +31,7 @@ .\" @(#)find.1 8.7 (Berkeley) 5/9/95 .\" $FreeBSD$ .\" -.Dd November 18, 2012 +.Dd January 5, 2014 .Dt FIND 1 .Os .Sh NAME @@ -520,6 +520,8 @@ Like .Ic -name , but the contents of the symbolic link are matched instead of the file name. +Note that this only matches broken symbolic links +if symbolic links are being followed. This is a GNU find extension. .It Ic -ls This primary always evaluates to true. diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index b65709948bb..9f156756cc5 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -1125,7 +1125,17 @@ f_name(PLAN *plan, FTSENT *entry) ssize_t len; if (plan->flags & F_LINK) { - len = readlink(entry->fts_path, fn, sizeof(fn) - 1); + /* + * The below test both avoids obviously useless readlink() + * calls and ensures that symlinks with existent target do + * not match if symlinks are being followed. + * Assumption: fts will stat all symlinks that are to be + * followed and will return the stat information. + */ + if (entry->fts_info != FTS_NSOK && entry->fts_info != FTS_SL && + entry->fts_info != FTS_SLNONE) + return 0; + len = readlink(entry->fts_accpath, fn, sizeof(fn) - 1); if (len == -1) return 0; fn[len] = '\0';