xref: /freebsd/lib/libc/gen/fts.3 (revision c27f7d6b9cf6d4ab01cb3d0972726c14e0aca146)
1.\" Copyright (c) 1989, 1991, 1993, 1994
2.\"	The Regents of the University of California.  All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\"    may be used to endorse or promote products derived from this software
14.\"    without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.Dd May 7, 2025
29.Dt FTS 3
30.Os
31.Sh NAME
32.Nm fts
33.Nd traverse a file hierarchy
34.Sh LIBRARY
35.Lb libc
36.Sh SYNOPSIS
37.In fts.h
38.Ft FTS *
39.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT * const *, const FTSENT * const *)"
40.Ft FTS *
41.Fn fts_open_b "char * const *path_argv" "int options" "int (^compar)(const FTSENT * const *, const FTSENT * const *)"
42.Ft FTSENT *
43.Fn fts_read "FTS *ftsp"
44.Ft FTSENT *
45.Fn fts_children "FTS *ftsp" "int options"
46.Ft int
47.Fn fts_set "FTS *ftsp" "FTSENT *f" "int options"
48.Ft void
49.Fn fts_set_clientptr "FTS *ftsp" "void *clientdata"
50.Ft void *
51.Fn fts_get_clientptr "FTS *ftsp"
52.Ft FTS *
53.Fn fts_get_stream "FTSENT *f"
54.Ft int
55.Fn fts_close "FTS *ftsp"
56.Sh DESCRIPTION
57The
58.Nm
59functions are provided for traversing
60.Ux
61file hierarchies.
62A simple overview is that the
63.Fn fts_open
64and
65.Fn fts_open_b
66functions return a
67.Dq handle
68on a file hierarchy, which is then supplied to
69the other
70.Nm
71functions.
72The function
73.Fn fts_read
74returns a pointer to a structure describing one of the files in the file
75hierarchy.
76The function
77.Fn fts_children
78returns a pointer to a linked list of structures, each of which describes
79one of the files contained in a directory in the hierarchy.
80In general, directories are visited two distinguishable times; in pre-order
81(before any of their descendants are visited) and in post-order (after all
82of their descendants have been visited).
83Files are visited once.
84It is possible to walk the hierarchy
85.Dq logically
86(ignoring symbolic links)
87or physically (visiting symbolic links), order the walk of the hierarchy or
88prune and/or re-visit portions of the hierarchy.
89.Pp
90Two structures are defined (and typedef'd) in the include file
91.In fts.h .
92The first is
93.Vt FTS ,
94the structure that represents the file hierarchy itself.
95The second is
96.Vt FTSENT ,
97the structure that represents a file in the file
98hierarchy.
99Normally, an
100.Vt FTSENT
101structure is returned for every file in the file
102hierarchy.
103In this manual page,
104.Dq file
105and
106.Dq Vt FTSENT No structure
107are generally
108interchangeable.
109.Pp
110The
111.Vt FTS
112structure contains space for a single pointer, which may be used to
113store application data or per-hierarchy state.
114The
115.Fn fts_set_clientptr
116and
117.Fn fts_get_clientptr
118functions may be used to set and retrieve this pointer.
119This is likely to be useful only when accessed from the sort
120comparison function, which can determine the original
121.Vt FTS
122stream of its arguments using the
123.Fn fts_get_stream
124function.
125The two
126.Li get
127functions are also available as macros of the same name.
128.Pp
129The
130.Vt FTSENT
131structure contains at least the following fields, which are
132described in greater detail below:
133.Bd -literal
134typedef struct _ftsent {
135	int fts_info;			/* status for FTSENT structure */
136	char *fts_accpath;		/* access path */
137	char *fts_path;			/* root path */
138	size_t fts_pathlen;		/* strlen(fts_path) */
139	char *fts_name;			/* file name */
140	size_t fts_namelen;		/* strlen(fts_name) */
141	long fts_level;			/* depth (\-1 to N) */
142	int fts_errno;			/* file errno */
143	long long fts_number;		/* local numeric value */
144	void *fts_pointer;		/* local address value */
145	struct ftsent *fts_parent;	/* parent directory */
146	struct ftsent *fts_link;	/* next file structure */
147	struct ftsent *fts_cycle;	/* cycle structure */
148	struct stat *fts_statp;		/* stat(2) information */
149} FTSENT;
150.Ed
151.Pp
152These fields are defined as follows:
153.Bl -tag -width "fts_namelen"
154.It Fa fts_info
155One of the following values describing the returned
156.Vt FTSENT
157structure and
158the file it represents.
159With the exception of directories without errors
160.Pq Dv FTS_D ,
161all of these
162entries are terminal, that is, they will not be revisited, nor will any
163of their descendants be visited.
164.Bl  -tag -width FTS_DEFAULT
165.It Dv FTS_D
166A directory being visited in pre-order.
167.It Dv FTS_DC
168A directory that causes a cycle in the tree.
169(The
170.Fa fts_cycle
171field of the
172.Vt FTSENT
173structure will be filled in as well.)
174.It Dv FTS_DEFAULT
175Any
176.Vt FTSENT
177structure that represents a file type not explicitly described
178by one of the other
179.Fa fts_info
180values.
181.It Dv FTS_DNR
182A directory which cannot be read.
183This is an error return, and the
184.Fa fts_errno
185field will be set to indicate what caused the error.
186.It Dv FTS_DOT
187A file named
188.Ql .\&
189or
190.Ql ..\&
191which was not specified as a file name to
192.Fn fts_open
193or
194.Fn fts_open_b
195(see
196.Dv FTS_SEEDOT ) .
197.It Dv FTS_DP
198A directory being visited in post-order.
199The contents of the
200.Vt FTSENT
201structure will be unchanged from when
202the directory was visited in pre-order, except for the
203.Fa fts_info
204field.
205.It Dv FTS_ERR
206This is an error return, and the
207.Fa fts_errno
208field will be set to indicate what caused the error.
209.It Dv FTS_F
210A regular file.
211.It Dv FTS_NS
212A file for which no
213.Xr stat 2
214information was available.
215The contents of the
216.Fa fts_statp
217field are undefined.
218This is an error return, and the
219.Fa fts_errno
220field will be set to indicate what caused the error.
221.It Dv FTS_NSOK
222A file for which no
223.Xr stat 2
224information was requested.
225The contents of the
226.Fa fts_statp
227field are undefined.
228.It Dv FTS_SL
229A symbolic link.
230.It Dv FTS_SLNONE
231A symbolic link with a non-existent target.
232The contents of the
233.Fa fts_statp
234field reference the file characteristic information for the symbolic link
235itself.
236.El
237.It Fa fts_accpath
238A path for accessing the file from the current directory.
239.It Fa fts_path
240The path for the file relative to the root of the traversal.
241This path contains the path specified to
242.Fn fts_open
243or
244.Fn fts_open_b
245as a prefix.
246.It Fa fts_pathlen
247The length of the string referenced by
248.Fa fts_path .
249.It Fa fts_name
250The name of the file.
251.It Fa fts_namelen
252The length of the string referenced by
253.Fa fts_name .
254.It Fa fts_level
255The depth of the traversal, numbered from \-1 to N, where this file
256was found.
257The
258.Vt FTSENT
259structure representing the parent of the starting point (or root)
260of the traversal is numbered
261.Dv FTS_ROOTPARENTLEVEL
262(\-1), and the
263.Vt FTSENT
264structure for the root
265itself is numbered
266.Dv FTS_ROOTLEVEL
267(0).
268.It Fa fts_errno
269Upon return of a
270.Vt FTSENT
271structure from the
272.Fn fts_children
273or
274.Fn fts_read
275functions, with its
276.Fa fts_info
277field set to
278.Dv FTS_DNR ,
279.Dv FTS_ERR
280or
281.Dv FTS_NS ,
282the
283.Fa fts_errno
284field contains the value of the external variable
285.Va errno
286specifying the cause of the error.
287Otherwise, the contents of the
288.Fa fts_errno
289field are undefined.
290.It Fa fts_number
291This field is provided for the use of the application program and is
292not modified by the
293.Nm
294functions.
295It is initialized to 0.
296.It Fa fts_pointer
297This field is provided for the use of the application program and is
298not modified by the
299.Nm
300functions.
301It is initialized to
302.Dv NULL .
303.It Fa fts_parent
304A pointer to the
305.Vt FTSENT
306structure referencing the file in the hierarchy
307immediately above the current file, i.e., the directory of which this
308file is a member.
309A parent structure for the initial entry point is provided as well,
310however, only the
311.Fa fts_level ,
312.Fa fts_number
313and
314.Fa fts_pointer
315fields are guaranteed to be initialized.
316.It Fa fts_link
317Upon return from the
318.Fn fts_children
319function, the
320.Fa fts_link
321field points to the next structure in the NULL-terminated linked list of
322directory members.
323Otherwise, the contents of the
324.Fa fts_link
325field are undefined.
326.It Fa fts_cycle
327If a directory causes a cycle in the hierarchy (see
328.Dv FTS_DC ) ,
329either because
330of a hard link between two directories, or a symbolic link pointing to a
331directory, the
332.Fa fts_cycle
333field of the structure will point to the
334.Vt FTSENT
335structure in the hierarchy that references the same file as the current
336.Vt FTSENT
337structure.
338Otherwise, the contents of the
339.Fa fts_cycle
340field are undefined.
341.It Fa fts_statp
342A pointer to
343.Xr stat 2
344information for the file.
345.El
346.Pp
347A single buffer is used for all of the paths of all of the files in the
348file hierarchy.
349Therefore, the
350.Fa fts_path
351and
352.Fa fts_accpath
353fields are guaranteed to be
354.Dv NUL Ns -terminated
355.Em only
356for the file most recently returned by
357.Fn fts_read .
358To use these fields to reference any files represented by other
359.Vt FTSENT
360structures will require that the path buffer be modified using the
361information contained in that
362.Vt FTSENT
363structure's
364.Fa fts_pathlen
365field.
366Any such modifications should be undone before further calls to
367.Fn fts_read
368are attempted.
369The
370.Fa fts_name
371field is always
372.Dv NUL Ns -terminated .
373.Sh FTS_OPEN
374The
375.Fn fts_open
376function takes a pointer to an array of character pointers naming one
377or more paths which make up a logical file hierarchy to be traversed.
378The array must be terminated by a
379.Dv NULL
380pointer.
381.Pp
382There are
383a number of options, at least one of which (either
384.Dv FTS_LOGICAL
385or
386.Dv FTS_PHYSICAL )
387must be specified.
388The options are selected by
389.Em or Ns 'ing
390the following values:
391.Bl -tag -width "FTS_PHYSICAL"
392.It Dv FTS_COMFOLLOW
393This option causes any symbolic link specified as a root path to be
394followed immediately whether or not
395.Dv FTS_LOGICAL
396is also specified.
397.It Dv FTS_COMFOLLOWDIR
398This option is similar to
399.Dv FTS_COMFOLLOW ,
400but only follows symbolic links to directories.
401.It Dv FTS_LOGICAL
402This option causes the
403.Nm
404routines to return
405.Vt FTSENT
406structures for the targets of symbolic links
407instead of the symbolic links themselves.
408If this option is set, the only symbolic links for which
409.Vt FTSENT
410structures
411are returned to the application are those referencing non-existent files.
412Either
413.Dv FTS_LOGICAL
414or
415.Dv FTS_PHYSICAL
416.Em must
417be provided to the
418.Fn fts_open
419function.
420.It Dv FTS_NOCHDIR
421To allow descending to arbitrary depths
422(independent of
423.Brq Dv PATH_MAX )
424and improve performance, the
425.Nm
426functions change directories as they walk the file hierarchy.
427This has the side-effect that an application cannot rely on being
428in any particular directory during the traversal.
429The
430.Dv FTS_NOCHDIR
431option turns off this feature, and the
432.Nm
433functions will not change the current directory.
434Note that applications should not themselves change their current directory
435and try to access files unless
436.Dv FTS_NOCHDIR
437is specified and absolute
438pathnames were provided as arguments to
439.Fn fts_open .
440.It Dv FTS_NOSTAT
441By default, returned
442.Vt FTSENT
443structures reference file characteristic information (the
444.Fa statp
445field) for each file visited.
446This option relaxes that requirement as a performance optimization,
447allowing the
448.Nm
449functions to set the
450.Fa fts_info
451field to
452.Dv FTS_NSOK
453and leave the contents of the
454.Fa statp
455field undefined.
456.It Dv FTS_NOSTAT_TYPE
457This option is similar to
458.Dv FTS_NOSTAT ,
459but attempts to populate
460.Fa fts_info
461based on information from the
462.Fa d_type
463field of
464.Vt struct dirent .
465.It Dv FTS_PHYSICAL
466This option causes the
467.Nm
468routines to return
469.Vt FTSENT
470structures for symbolic links themselves instead
471of the target files they point to.
472If this option is set,
473.Vt FTSENT
474structures for all symbolic links in the
475hierarchy are returned to the application.
476Either
477.Dv FTS_LOGICAL
478or
479.Dv FTS_PHYSICAL
480.Em must
481be provided to the
482.Fn fts_open
483function.
484.It Dv FTS_SEEDOT
485By default, unless they are specified as path arguments to
486.Fn fts_open ,
487any files named
488.Ql .\&
489or
490.Ql ..\&
491encountered in the file hierarchy are ignored.
492This option causes the
493.Nm
494routines to return
495.Vt FTSENT
496structures for them.
497.It Dv FTS_XDEV
498This option prevents
499.Nm
500from descending into directories that have a different device number
501than the file from which the descent began.
502.El
503.Pp
504The argument
505.Fn compar
506specifies a user-defined function which may be used to order the traversal
507of the hierarchy.
508It
509takes two pointers to pointers to
510.Vt FTSENT
511structures as arguments and
512should return a negative value, zero, or a positive value to indicate
513if the file referenced by its first argument comes before, in any order
514with respect to, or after, the file referenced by its second argument.
515The
516.Fa fts_accpath ,
517.Fa fts_path
518and
519.Fa fts_pathlen
520fields of the
521.Vt FTSENT
522structures may
523.Em never
524be used in this comparison.
525If the
526.Fa fts_info
527field is set to
528.Dv FTS_NS
529or
530.Dv FTS_NSOK ,
531the
532.Fa fts_statp
533field may not either.
534If the
535.Fn compar
536argument is
537.Dv NULL ,
538the directory traversal order is in the order listed in
539.Fa path_argv
540for the root paths, and in the order listed in the directory for
541everything else.
542.Sh FTS_OPEN_B
543The
544.Fn fts_open_b
545function is identical to
546.Fn fts_open
547except that it takes a block pointer instead of a function pointer.
548The block is copied before
549.Fn fts_open_b
550returns, so the original can safely go out of scope or be released.
551.Sh FTS_READ
552The
553.Fn fts_read
554function returns a pointer to an
555.Vt FTSENT
556structure describing a file in
557the hierarchy.
558Directories (that are readable and do not cause cycles) are visited at
559least twice, once in pre-order and once in post-order.
560All other files are visited at least once.
561(Hard links between directories that do not cause cycles or symbolic
562links to symbolic links may cause files to be visited more than once,
563or directories more than twice.)
564.Pp
565If all the members of the hierarchy have been returned,
566.Fn fts_read
567returns
568.Dv NULL
569and sets the external variable
570.Va errno
571to 0.
572If an error unrelated to a file in the hierarchy occurs,
573.Fn fts_read
574returns
575.Dv NULL
576and sets
577.Va errno
578appropriately.
579If an error related to a returned file occurs, a pointer to an
580.Vt FTSENT
581structure is returned, and
582.Va errno
583may or may not have been set (see
584.Fa fts_info ) .
585.Pp
586The
587.Vt FTSENT
588structures returned by
589.Fn fts_read
590may be overwritten after a call to
591.Fn fts_close
592on the same file hierarchy stream, or, after a call to
593.Fn fts_read
594on the same file hierarchy stream unless they represent a file of type
595directory, in which case they will not be overwritten until after a call to
596.Fn fts_read
597after the
598.Vt FTSENT
599structure has been returned by the function
600.Fn fts_read
601in post-order.
602.Sh FTS_CHILDREN
603The
604.Fn fts_children
605function returns a pointer to an
606.Vt FTSENT
607structure describing the first entry in a NULL-terminated linked list of
608the files in the directory represented by the
609.Vt FTSENT
610structure most recently returned by
611.Fn fts_read .
612The list is linked through the
613.Fa fts_link
614field of the
615.Vt FTSENT
616structure, and is ordered by the user-specified comparison function, if any.
617Repeated calls to
618.Fn fts_children
619will recreate this linked list.
620.Pp
621As a special case, if
622.Fn fts_read
623has not yet been called for a hierarchy,
624.Fn fts_children
625will return a pointer to the files in the logical directory specified to
626.Fn fts_open
627or
628.Fn fts_open_b ,
629i.e., the arguments specified to
630.Fn fts_open
631or
632.Fn fts_open_b .
633Otherwise, if the
634.Vt FTSENT
635structure most recently returned by
636.Fn fts_read
637is not a directory being visited in pre-order,
638or the directory does not contain any files,
639.Fn fts_children
640returns
641.Dv NULL
642and sets
643.Va errno
644to zero.
645If an error occurs,
646.Fn fts_children
647returns
648.Dv NULL
649and sets
650.Va errno
651appropriately.
652.Pp
653The
654.Vt FTSENT
655structures returned by
656.Fn fts_children
657may be overwritten after a call to
658.Fn fts_children ,
659.Fn fts_close
660or
661.Fn fts_read
662on the same file hierarchy stream.
663.Pp
664.Em Option
665may be set to the following value:
666.Bl -tag -width FTS_NAMEONLY
667.It Dv FTS_NAMEONLY
668Only the names of the files are needed.
669The contents of all the fields in the returned linked list of structures
670are undefined with the exception of the
671.Fa fts_name
672and
673.Fa fts_namelen
674fields.
675.El
676.Sh FTS_SET
677The function
678.Fn fts_set
679allows the user application to determine further processing for the
680file
681.Fa f
682of the stream
683.Fa ftsp .
684The
685.Fn fts_set
686function
687returns 0 on success, and \-1 if an error occurs.
688.Em Option
689must be set to one of the following values:
690.Bl -tag -width FTS_PHYSICAL
691.It Dv FTS_AGAIN
692Re-visit the file; any file type may be re-visited.
693The next call to
694.Fn fts_read
695will return the referenced file.
696The
697.Fa fts_stat
698and
699.Fa fts_info
700fields of the structure will be reinitialized at that time,
701but no other fields will have been changed.
702This option is meaningful only for the most recently returned
703file from
704.Fn fts_read .
705Normal use is for post-order directory visits, where it causes the
706directory to be re-visited (in both pre and post-order) as well as all
707of its descendants.
708.It Dv FTS_FOLLOW
709The referenced file must be a symbolic link.
710If the referenced file is the one most recently returned by
711.Fn fts_read ,
712the next call to
713.Fn fts_read
714returns the file with the
715.Fa fts_info
716and
717.Fa fts_statp
718fields reinitialized to reflect the target of the symbolic link instead
719of the symbolic link itself.
720If the file is one of those most recently returned by
721.Fn fts_children ,
722the
723.Fa fts_info
724and
725.Fa fts_statp
726fields of the structure, when returned by
727.Fn fts_read ,
728will reflect the target of the symbolic link instead of the symbolic link
729itself.
730In either case, if the target of the symbolic link does not exist the
731fields of the returned structure will be unchanged and the
732.Fa fts_info
733field will be set to
734.Dv FTS_SLNONE .
735.Pp
736If the target of the link is a directory, the pre-order return, followed
737by the return of all of its descendants, followed by a post-order return,
738is done.
739.It Dv FTS_SKIP
740No descendants of this file are visited.
741The file may be one of those most recently returned by either
742.Fn fts_children
743or
744.Fn fts_read .
745.El
746.Sh FTS_CLOSE
747The
748.Fn fts_close
749function closes a file hierarchy stream
750.Fa ftsp
751and restores the current directory to the directory from which
752.Fn fts_open
753or
754.Fn fts_open_b
755was called to open
756.Fa ftsp .
757The
758.Fn fts_close
759function
760returns 0 on success, and \-1 if an error occurs.
761.Sh ERRORS
762The
763.Fn fts_open
764and
765.Fn fts_open_b
766functions may fail and set
767.Va errno
768for any of the errors specified for the library functions
769.Xr open 2
770and
771.Xr malloc 3 .
772The
773.Fn fts_open_b
774function may also fail and set
775.Va errno
776to
777.Dv ENOSYS
778if the blocks runtime is missing.
779.Pp
780The
781.Fn fts_close
782function may fail and set
783.Va errno
784for any of the errors specified for the library functions
785.Xr chdir 2
786and
787.Xr close 2 .
788.Pp
789The
790.Fn fts_read
791and
792.Fn fts_children
793functions may fail and set
794.Va errno
795for any of the errors specified for the library functions
796.Xr chdir 2 ,
797.Xr malloc 3 ,
798.Xr opendir 3 ,
799.Xr readdir 3
800and
801.Xr stat 2 .
802.Pp
803In addition, the
804.Fn fts_children ,
805.Fn fts_open ,
806and
807.Fn fts_set
808functions may fail and set
809.Va errno
810as follows:
811.Bl -tag -width Er
812.It Bq Er EINVAL
813The options were invalid, or the list were empty.
814.El
815.Sh SEE ALSO
816.Xr find 1 ,
817.Xr chdir 2 ,
818.Xr stat 2 ,
819.Xr ftw 3 ,
820.Xr qsort 3
821.Sh HISTORY
822The
823.Nm
824interface was first introduced in
825.Bx 4.4 .
826The
827.Fn fts_get_clientptr ,
828.Fn fts_get_stream ,
829and
830.Fn fts_set_clientptr
831functions were introduced in
832.Fx 5.0 ,
833principally to provide for alternative interfaces to the
834.Nm
835functionality using different data structures.
836Blocks support and the
837.Dv FTS_COMFOLLOWDIR
838and
839.Dv FTS_NOSTAT
840options were added in
841.Fx 15.0
842based on similar functionality in macOS.
843.Sh BUGS
844The
845.Fn fts_open
846function will automatically set the
847.Dv FTS_NOCHDIR
848option if the
849.Dv FTS_LOGICAL
850option is provided, or if it cannot
851.Xr open 2
852the current directory.
853