xref: /freebsd/lib/libc/gen/fts.3 (revision 92f340d137ba5d6db7610ba1dae35842e2c9c8ea)
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 April 17, 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_LOGICAL
398This option causes the
399.Nm
400routines to return
401.Vt FTSENT
402structures for the targets of symbolic links
403instead of the symbolic links themselves.
404If this option is set, the only symbolic links for which
405.Vt FTSENT
406structures
407are returned to the application are those referencing non-existent files.
408Either
409.Dv FTS_LOGICAL
410or
411.Dv FTS_PHYSICAL
412.Em must
413be provided to the
414.Fn fts_open
415function.
416.It Dv FTS_NOCHDIR
417To allow descending to arbitrary depths
418(independent of
419.Brq Dv PATH_MAX )
420and improve performance, the
421.Nm
422functions change directories as they walk the file hierarchy.
423This has the side-effect that an application cannot rely on being
424in any particular directory during the traversal.
425The
426.Dv FTS_NOCHDIR
427option turns off this feature, and the
428.Nm
429functions will not change the current directory.
430Note that applications should not themselves change their current directory
431and try to access files unless
432.Dv FTS_NOCHDIR
433is specified and absolute
434pathnames were provided as arguments to
435.Fn fts_open .
436.It Dv FTS_NOSTAT
437By default, returned
438.Vt FTSENT
439structures reference file characteristic information (the
440.Fa statp
441field) for each file visited.
442This option relaxes that requirement as a performance optimization,
443allowing the
444.Nm
445functions to set the
446.Fa fts_info
447field to
448.Dv FTS_NSOK
449and leave the contents of the
450.Fa statp
451field undefined.
452.It Dv FTS_PHYSICAL
453This option causes the
454.Nm
455routines to return
456.Vt FTSENT
457structures for symbolic links themselves instead
458of the target files they point to.
459If this option is set,
460.Vt FTSENT
461structures for all symbolic links in the
462hierarchy are returned to the application.
463Either
464.Dv FTS_LOGICAL
465or
466.Dv FTS_PHYSICAL
467.Em must
468be provided to the
469.Fn fts_open
470function.
471.It Dv FTS_SEEDOT
472By default, unless they are specified as path arguments to
473.Fn fts_open ,
474any files named
475.Ql .\&
476or
477.Ql ..\&
478encountered in the file hierarchy are ignored.
479This option causes the
480.Nm
481routines to return
482.Vt FTSENT
483structures for them.
484.It Dv FTS_XDEV
485This option prevents
486.Nm
487from descending into directories that have a different device number
488than the file from which the descent began.
489.El
490.Pp
491The argument
492.Fn compar
493specifies a user-defined function which may be used to order the traversal
494of the hierarchy.
495It
496takes two pointers to pointers to
497.Vt FTSENT
498structures as arguments and
499should return a negative value, zero, or a positive value to indicate
500if the file referenced by its first argument comes before, in any order
501with respect to, or after, the file referenced by its second argument.
502The
503.Fa fts_accpath ,
504.Fa fts_path
505and
506.Fa fts_pathlen
507fields of the
508.Vt FTSENT
509structures may
510.Em never
511be used in this comparison.
512If the
513.Fa fts_info
514field is set to
515.Dv FTS_NS
516or
517.Dv FTS_NSOK ,
518the
519.Fa fts_statp
520field may not either.
521If the
522.Fn compar
523argument is
524.Dv NULL ,
525the directory traversal order is in the order listed in
526.Fa path_argv
527for the root paths, and in the order listed in the directory for
528everything else.
529.Sh FTS_OPEN_B
530The
531.Fn fts_open_b
532function is identical to
533.Fn fts_open
534except that it takes a block pointer instead of a function pointer.
535The block is copied before
536.Fn fts_open_b
537returns, so the original can safely go out of scope or be released.
538.Sh FTS_READ
539The
540.Fn fts_read
541function returns a pointer to an
542.Vt FTSENT
543structure describing a file in
544the hierarchy.
545Directories (that are readable and do not cause cycles) are visited at
546least twice, once in pre-order and once in post-order.
547All other files are visited at least once.
548(Hard links between directories that do not cause cycles or symbolic
549links to symbolic links may cause files to be visited more than once,
550or directories more than twice.)
551.Pp
552If all the members of the hierarchy have been returned,
553.Fn fts_read
554returns
555.Dv NULL
556and sets the external variable
557.Va errno
558to 0.
559If an error unrelated to a file in the hierarchy occurs,
560.Fn fts_read
561returns
562.Dv NULL
563and sets
564.Va errno
565appropriately.
566If an error related to a returned file occurs, a pointer to an
567.Vt FTSENT
568structure is returned, and
569.Va errno
570may or may not have been set (see
571.Fa fts_info ) .
572.Pp
573The
574.Vt FTSENT
575structures returned by
576.Fn fts_read
577may be overwritten after a call to
578.Fn fts_close
579on the same file hierarchy stream, or, after a call to
580.Fn fts_read
581on the same file hierarchy stream unless they represent a file of type
582directory, in which case they will not be overwritten until after a call to
583.Fn fts_read
584after the
585.Vt FTSENT
586structure has been returned by the function
587.Fn fts_read
588in post-order.
589.Sh FTS_CHILDREN
590The
591.Fn fts_children
592function returns a pointer to an
593.Vt FTSENT
594structure describing the first entry in a NULL-terminated linked list of
595the files in the directory represented by the
596.Vt FTSENT
597structure most recently returned by
598.Fn fts_read .
599The list is linked through the
600.Fa fts_link
601field of the
602.Vt FTSENT
603structure, and is ordered by the user-specified comparison function, if any.
604Repeated calls to
605.Fn fts_children
606will recreate this linked list.
607.Pp
608As a special case, if
609.Fn fts_read
610has not yet been called for a hierarchy,
611.Fn fts_children
612will return a pointer to the files in the logical directory specified to
613.Fn fts_open
614or
615.Fn fts_open_b ,
616i.e., the arguments specified to
617.Fn fts_open
618or
619.Fn fts_open_b .
620Otherwise, if the
621.Vt FTSENT
622structure most recently returned by
623.Fn fts_read
624is not a directory being visited in pre-order,
625or the directory does not contain any files,
626.Fn fts_children
627returns
628.Dv NULL
629and sets
630.Va errno
631to zero.
632If an error occurs,
633.Fn fts_children
634returns
635.Dv NULL
636and sets
637.Va errno
638appropriately.
639.Pp
640The
641.Vt FTSENT
642structures returned by
643.Fn fts_children
644may be overwritten after a call to
645.Fn fts_children ,
646.Fn fts_close
647or
648.Fn fts_read
649on the same file hierarchy stream.
650.Pp
651.Em Option
652may be set to the following value:
653.Bl -tag -width FTS_NAMEONLY
654.It Dv FTS_NAMEONLY
655Only the names of the files are needed.
656The contents of all the fields in the returned linked list of structures
657are undefined with the exception of the
658.Fa fts_name
659and
660.Fa fts_namelen
661fields.
662.El
663.Sh FTS_SET
664The function
665.Fn fts_set
666allows the user application to determine further processing for the
667file
668.Fa f
669of the stream
670.Fa ftsp .
671The
672.Fn fts_set
673function
674returns 0 on success, and \-1 if an error occurs.
675.Em Option
676must be set to one of the following values:
677.Bl -tag -width FTS_PHYSICAL
678.It Dv FTS_AGAIN
679Re-visit the file; any file type may be re-visited.
680The next call to
681.Fn fts_read
682will return the referenced file.
683The
684.Fa fts_stat
685and
686.Fa fts_info
687fields of the structure will be reinitialized at that time,
688but no other fields will have been changed.
689This option is meaningful only for the most recently returned
690file from
691.Fn fts_read .
692Normal use is for post-order directory visits, where it causes the
693directory to be re-visited (in both pre and post-order) as well as all
694of its descendants.
695.It Dv FTS_FOLLOW
696The referenced file must be a symbolic link.
697If the referenced file is the one most recently returned by
698.Fn fts_read ,
699the next call to
700.Fn fts_read
701returns the file with the
702.Fa fts_info
703and
704.Fa fts_statp
705fields reinitialized to reflect the target of the symbolic link instead
706of the symbolic link itself.
707If the file is one of those most recently returned by
708.Fn fts_children ,
709the
710.Fa fts_info
711and
712.Fa fts_statp
713fields of the structure, when returned by
714.Fn fts_read ,
715will reflect the target of the symbolic link instead of the symbolic link
716itself.
717In either case, if the target of the symbolic link does not exist the
718fields of the returned structure will be unchanged and the
719.Fa fts_info
720field will be set to
721.Dv FTS_SLNONE .
722.Pp
723If the target of the link is a directory, the pre-order return, followed
724by the return of all of its descendants, followed by a post-order return,
725is done.
726.It Dv FTS_SKIP
727No descendants of this file are visited.
728The file may be one of those most recently returned by either
729.Fn fts_children
730or
731.Fn fts_read .
732.El
733.Sh FTS_CLOSE
734The
735.Fn fts_close
736function closes a file hierarchy stream
737.Fa ftsp
738and restores the current directory to the directory from which
739.Fn fts_open
740or
741.Fn fts_open_b
742was called to open
743.Fa ftsp .
744The
745.Fn fts_close
746function
747returns 0 on success, and \-1 if an error occurs.
748.Sh ERRORS
749The
750.Fn fts_open
751and
752.Fn fts_open_b
753functions may fail and set
754.Va errno
755for any of the errors specified for the library functions
756.Xr open 2
757and
758.Xr malloc 3 .
759The
760.Fn fts_open_b
761function may also fail and set
762.Va errno
763to
764.Dv ENOSYS
765if the blocks runtime is missing.
766.Pp
767The
768.Fn fts_close
769function may fail and set
770.Va errno
771for any of the errors specified for the library functions
772.Xr chdir 2
773and
774.Xr close 2 .
775.Pp
776The
777.Fn fts_read
778and
779.Fn fts_children
780functions may fail and set
781.Va errno
782for any of the errors specified for the library functions
783.Xr chdir 2 ,
784.Xr malloc 3 ,
785.Xr opendir 3 ,
786.Xr readdir 3
787and
788.Xr stat 2 .
789.Pp
790In addition, the
791.Fn fts_children ,
792.Fn fts_open ,
793and
794.Fn fts_set
795functions may fail and set
796.Va errno
797as follows:
798.Bl -tag -width Er
799.It Bq Er EINVAL
800The options were invalid, or the list were empty.
801.El
802.Sh SEE ALSO
803.Xr find 1 ,
804.Xr chdir 2 ,
805.Xr stat 2 ,
806.Xr ftw 3 ,
807.Xr qsort 3
808.Sh HISTORY
809The
810.Nm
811interface was first introduced in
812.Bx 4.4 .
813The
814.Fn fts_get_clientptr ,
815.Fn fts_get_stream ,
816and
817.Fn fts_set_clientptr
818functions were introduced in
819.Fx 5.0 ,
820principally to provide for alternative interfaces to the
821.Nm
822functionality using different data structures.
823.Sh BUGS
824The
825.Fn fts_open
826function will automatically set the
827.Dv FTS_NOCHDIR
828option if the
829.Dv FTS_LOGICAL
830option is provided, or if it cannot
831.Xr open 2
832the current directory.
833