summaryrefslogtreecommitdiffstats
path: root/usr.bin/find
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2014-01-05 23:01:28 +0000
committerjilles <jilles@FreeBSD.org>2014-01-05 23:01:28 +0000
commite0cca1215ba95b5057ee368441bf414ed966627f (patch)
treeb4df40028a96c27e13ec1f1ab4e104b18b8803d0 /usr.bin/find
parent420aa503c6704f4bb0c18541b7c7c193388555e1 (diff)
downloadFreeBSD-src-e0cca1215ba95b5057ee368441bf414ed966627f.zip
FreeBSD-src-e0cca1215ba95b5057ee368441bf414ed966627f.tar.gz
find: Fix two more problems with -lname and -ilname:
* Do not match symlinks that are followed because of -H or -L. This is explicitly documented in GNU find's info file and is like -type l. * Fix matching symlinks in subdirectories when fts changes directories. Also, avoid some readlink() calls on files that are obviously not symlinks (because of fts(3) restrictions, not all of them). MFC after: 1 week
Diffstat (limited to 'usr.bin/find')
-rw-r--r--usr.bin/find/find.14
-rw-r--r--usr.bin/find/function.c12
2 files changed, 14 insertions, 2 deletions
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index cffeacf..1abe825 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 b657099..9f15675 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';
OpenPOWER on IntegriCloud