Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142069909
D50233.id155133.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D50233.id155133.diff
View Options
diff --git a/include/fts.h b/include/fts.h
--- a/include/fts.h
+++ b/include/fts.h
@@ -65,7 +65,11 @@
#define FTS_SEEDOT 0x000020 /* return dot and dot-dot */
#define FTS_XDEV 0x000040 /* don't cross devices */
#define FTS_WHITEOUT 0x000080 /* return whiteout information */
-#define FTS_OPTIONMASK 0x0000ff /* valid user option mask */
+ /* 0x0100 is FTS_NAMEONLY below */
+ /* 0x0200 was previously FTS_STOP */
+#define FTS_COMFOLLOWDIR 0x00400 /* like COMFOLLOW but directories only */
+#define FTS_NOSTAT_TYPE 0x000800 /* like NOSTAT but use d_type */
+#define FTS_OPTIONMASK 0x000cff /* valid user option mask */
/* valid only for fts_children() */
#define FTS_NAMEONLY 0x000100 /* child names only */
diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3
--- a/lib/libc/gen/fts.3
+++ b/lib/libc/gen/fts.3
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 17, 2025
+.Dd May 7, 2025
.Dt FTS 3
.Os
.Sh NAME
@@ -394,6 +394,10 @@
followed immediately whether or not
.Dv FTS_LOGICAL
is also specified.
+.It Dv FTS_COMFOLLOWDIR
+This option is similar to
+.Dv FTS_COMFOLLOW ,
+but only follows symbolic links to directories.
.It Dv FTS_LOGICAL
This option causes the
.Nm
@@ -449,6 +453,15 @@
and leave the contents of the
.Fa statp
field undefined.
+.It Dv FTS_NOSTAT_TYPE
+This option is similar to
+.Dv FTS_NOSTAT ,
+but attempts to populate
+.Fa fts_info
+based on information from the
+.Fa d_type
+field of
+.Vt struct dirent .
.It Dv FTS_PHYSICAL
This option causes the
.Nm
@@ -820,6 +833,13 @@
principally to provide for alternative interfaces to the
.Nm
functionality using different data structures.
+Blocks support and the
+.Dv FTS_COMFOLLOWDIR
+and
+.Dv FTS_NOSTAT
+options were added in
+.Fx 15.0
+based on similar functionality in macOS.
.Sh BUGS
The
.Fn fts_open
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -126,6 +126,10 @@
if (ISSET(FTS_LOGICAL))
SET(FTS_NOCHDIR);
+ /* NOSTAT_TYPE implies NOSTAT */
+ if (ISSET(FTS_NOSTAT_TYPE))
+ SET(FTS_NOSTAT);
+
/*
* Start out with 1K of path space, and enough, in any case,
* to hold the user's paths.
@@ -149,7 +153,9 @@
p->fts_level = FTS_ROOTLEVEL;
p->fts_parent = parent;
p->fts_accpath = p->fts_name;
- p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1);
+ p->fts_info = fts_stat(sp, p,
+ ISSET(FTS_COMFOLLOWDIR) ? -1 : ISSET(FTS_COMFOLLOW),
+ -1);
/* Command-line "." and ".." are real directories. */
if (p->fts_info == FTS_DOT)
@@ -904,6 +910,25 @@
p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
--nlinks;
}
+ if (p->fts_info == FTS_NSOK && ISSET(FTS_NOSTAT_TYPE)) {
+ switch (dp->d_type) {
+ case DT_FIFO:
+ case DT_CHR:
+ case DT_BLK:
+ case DT_SOCK:
+ p->fts_info = FTS_DEFAULT;
+ break;
+ case DT_REG:
+ p->fts_info = FTS_F;
+ break;
+ case DT_LNK:
+ p->fts_info = FTS_SL;
+ break;
+ case DT_WHT:
+ p->fts_info = FTS_W;
+ break;
+ }
+ }
/* We walk in directory order so "ls -f" doesn't get upset. */
p->fts_link = NULL;
@@ -980,7 +1005,7 @@
dev_t dev;
ino_t ino;
struct stat *sbp, sb;
- int saved_errno;
+ int ret, saved_errno;
const char *path;
if (dfd == -1) {
@@ -1003,19 +1028,25 @@
}
/*
- * If doing a logical walk, or application requested FTS_FOLLOW, do
- * a stat(2). If that fails, check for a non-existent symlink. If
- * fail, set the errno from the stat call.
+ * If doing a logical walk, or caller requested FTS_COMFOLLOW, do
+ * a full stat(2). If that fails, do an lstat(2) to check for a
+ * non-existent symlink. If that fails, set the errno from the
+ * stat(2) call.
+ *
+ * As a special case, if stat(2) succeeded but the target is not a
+ * directory and follow is negative (indicating FTS_COMFOLLOWDIR
+ * rather than FTS_COMFOLLOW), we also revert to lstat(2).
*/
if (ISSET(FTS_LOGICAL) || follow) {
- if (fstatat(dfd, path, sbp, 0)) {
+ if ((ret = fstatat(dfd, path, sbp, 0)) != 0 ||
+ (follow < 0 && !S_ISDIR(sbp->st_mode))) {
saved_errno = errno;
if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
p->fts_errno = saved_errno;
goto err;
}
errno = 0;
- if (S_ISLNK(sbp->st_mode))
+ if (ret != 0 && S_ISLNK(sbp->st_mode))
return (FTS_SLNONE);
}
} else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 16, 6:02 PM (15 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27664759
Default Alt Text
D50233.id155133.diff (4 KB)
Attached To
Mode
D50233: fts: Add FTS_COMFOLLOWDIR and FTS_NOSTAT_TYPE.
Attached
Detach File
Event Timeline
Log In to Comment