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