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