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