FTS - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-04-11
名称
fts,fts_open,fts_read,fts_children,fts_set,fts_close-遍历文件层次结构
语法
#include <sys/types.h> #include <sys/stat.h> #include <fts.h> FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)); FTSENT *fts_read(FTS *ftsp); FTSENT *fts_children(FTS *ftsp, int instr); int fts_set(FTS *ftsp, FTSENT *f, int instr); int fts_close(FTS *ftsp);
说明
提供fts函数以遍历文件层次结构。一个简单的概述是fts_open()函数返回一个"句柄"(类型为FTS *),该句柄引用文件层次结构"流"。然后将此手柄提供给其他fts功能。函数fts_read()返回一个指向结构的指针,该结构描述了文件层次结构中的一个文件。函数fts_children()返回一个指向链接的结构列表的指针,每个结构都描述了层次结构目录中包含的一个文件。
通常,访问目录有两个不同的时间:顺序(在访问其所有后代之前)和后序(在访问所有后代之后)。文件被访问一次。可以"逻辑地"遍历层次结构(访问符号链接指向的文件)或物理地遍历层次结构(访问符号链接本身),命令遍历层次结构或修剪和/或重新访问层次结构的各个部分。
在include文件中定义了两个结构(和关联的类型)。第一种类型是FTS,该结构表示文件层次结构本身。第二种类型是FTSENT,该结构表示文件层次结构中的文件。通常,将为文件层次结构中的每个文件返回FTSENT结构。在本手册页中,"文件"和" FTSENT结构"通常是可互换的。
FTSENT结构包含描述文件的字段。该结构至少包含以下字段(有些字段应视为实现的私有字段):
typedef struct _ftsent { unsigned short fts_info; /* flags for FTSENT structure */ char *fts_accpath; /* access path */ char *fts_path; /* root path */ short fts_pathlen; /* strlen(fts_path) + strlen(fts_name) */ char *fts_name; /* filename */ short fts_namelen; /* strlen(fts_name) */ short fts_level; /* depth (-1 to N) */ int fts_errno; /* file errno */ long fts_number; /* local numeric value */ void *fts_pointer; /* local address value */ struct _ftsent *fts_parent; /* parent directory */ struct _ftsent *fts_link; /* next file structure */ struct _ftsent *fts_cycle; /* cycle structure */ struct stat *fts_statp; /* stat(2) information */ } FTSENT;
这些字段定义如下:
- fts_info
- One of the following values describing the returned
FTSENT
structure and
the file it represents.
With the exception of directories without errors
(FTS_D),all of these
entries are terminal, that is, they will not be revisited, nor will any
of their descendants be visited.- FTS_D
- 正在按预定顺序访问目录。
- FTS_DC
- 导致树循环的目录。 (还将填写FTSENT结构的fts_cycle字段。)
- FTS_DEFAULT
- 表示未由其他fts_info值之一明确描述的文件类型的任何FTSENT结构。
- FTS_DNR
- 无法读取的目录。这是错误返回,并且将设置fts_errno字段以指示导致错误的原因。
- FTS_DOT
- 名为"。"的文件。或未指定为fts_open()的文件名的" .."(请参阅FTS_SEEDOT)。
- FTS_DP
- 邮递目录中正在访问的目录。 FTSENT结构的内容与以预定顺序返回时(即fts_info字段设置为FTS_D)相同。
- FTS_ERR
- 这是错误返回,并且将设置fts_errno字段以指示导致错误的原因。
- FTS_F
- 常规文件。
- FTS_NS
- 没有可用的stat(2)信息的文件。 fts_statp字段的内容未定义。这是错误返回,并且将设置fts_errno字段以指示导致错误的原因。
- FTS_NSOK
- 没有请求stat(2)信息的文件。 fts_statp字段的内容未定义。
- FTS_SL
- 一个符号链接。
- FTS_SLNONE
- 目标不存在的符号链接。 fts_statp字段的内容引用符号链接本身的文件特征信息。
- fts_accpath
- 从当前目录访问文件的路径。
- fts_path
- 相对于遍历根的文件路径。该路径包含指定给fts_open()的路径作为前缀。
- fts_pathlen
- fts_path和fts_name引用的字符串的长度之和。
- fts_name
- 文件名。
- fts_namelen
- fts_name引用的字符串的长度。
- fts_level
- 遍历的深度,从-1到N,在此文件中找到。表示遍历的起点(或根)的父级的FTSENT结构编号为-1,而根本身的FTSENT结构编号为0。
- fts_errno
- 如果fts_children()或fts_read()返回其fts_info字段设置为FTS_DNR,FTS_ERR或FTS_NS的FTSENT结构,则fts_errno字段包含指定错误原因的错误号(即errno值)。否则,fts_errno字段的内容未定义。
- fts_number
- 提供此字段供应用程序使用,并且不会被fts函数修改。初始化为0。
- fts_pointer
- 提供此字段供应用程序使用,并且不会被fts函数修改。它被初始化为NULL。
- fts_parent
- 指向FTSENT结构的指针,该结构在当前文件正上方的层次结构中引用该文件,即该文件所属的目录。还提供了初始入口点的父结构,但是,只有fts_level,fts_number和fts_pointer字段可以保证被初始化。
- fts_link
- 从fts_children()函数返回后,fts_link字段指向目录成员以NULL终止的链接列表中的下一个结构。否则,未定义fts_link字段的内容。
- fts_cycle
- 如果目录由于两个目录之间的硬链接或指向目录的符号链接而导致层次结构中的循环(请参阅FTS_DC),则该结构的fts_cycle字段将指向引用该层次结构中的FTSENT结构与当前FTSENT结构相同的文件。否则,fts_cycle字段的内容未定义。
- fts_statp
- 指向文件的stat(2)信息的指针。
单个缓冲区用于文件层次结构中所有文件的所有路径。因此,仅对于fts_read()最近返回的文件,保证fts_path和fts_accpath字段以空值结尾。要使用这些字段引用由其他FTSENT结构表示的任何文件,将需要使用该FTSENT结构的fts_pathlen字段中包含的信息来修改路径缓冲区。在尝试进一步调用fts_read()之前,应撤消任何此类修改。 fts_name字段始终为空终止。
fts_open()
fts_open()函数采用一个指向字符指针数组的指针,该数组命名一个或多个路径,这些路径构成了要遍历的逻辑文件层次结构。该数组必须以空指针终止。
有很多选项,至少必须指定其中一个(FTS_LOGICAL或FTS_PHYSICAL)。通过对以下值进行"或"运算来选择选项:
- FTS_COMFOLLOW
- 无论是否还指定了FTS_LOGICAL,此选项都会导致立即跟随任何指定为根路径的符号链接。
- FTS_LOGICAL
- 此选项使fts例程返回符号链接目标的FTSENT结构,而不是符号链接本身。如果设置了此选项,则返回FTSENT结构到应用程序的符号链接只有那些引用不存在的文件的符号链接。必须向fts_open()函数提供FTS_LOGICAL或FTS_PHYSICAL。
- FTS_NOCHDIR
- 作为性能优化,fts函数在遍历文件层次结构时更改目录。这具有副作用,即应用程序在遍历期间不能依赖于位于任何特定目录中。 FTS_NOCHDIR选项关闭此优化,并且fts函数不会更改当前目录。请注意,除非指定了FTS_NOCHDIR且提供了绝对路径名作为fts_open()的参数,否则应用程序本身不应更改其当前目录并尝试访问文件。
- FTS_NOSTAT
- 默认情况下,返回的FTSENT结构会为访问的每个文件参考文件特征信息(statp字段)。此选项放宽了对性能优化的要求,允许fts函数将fts_info字段设置为FTS_NSOK并保留statp字段的内容未定义。
- FTS_PHYSICAL
- 此选项使fts例程返回符号链接本身的FTSENT结构,而不是它们指向的目标文件。如果设置此选项,则层次结构中所有符号链接的FTSENT结构将返回给应用程序。必须向fts_open()函数提供FTS_LOGICAL或FTS_PHYSICAL。
- FTS_SEEDOT
- 默认情况下,除非将它们指定为fts_open()的路径参数,否则任何名为"。"的文件。或在文件层次结构中遇到的" .."将被忽略。此选项使fts例程为其返回FTSENT结构。
- FTS_XDEV
- 此选项可防止fts进入目录号不同于下降源文件的目录。
参数compar()指定一个用户定义的函数,该函数可用于对层次结构的遍历进行排序。它使用两个指向FTSENT结构的指针作为参数,并应返回负值,零或正值,以指示其第一个参数所引用的文件相对于所引用的文件之前,之后或之后的顺序是否正确。根据第二个论点。 FTSENT结构的fts_accpath,fts_path和fts_pathlen字段可能永远不会用于此比较。如果fts_info字段设置为FTS_NS或FTS_NSOK,则fts_statp字段也可能不会。如果compar()参数为NULL,则目录遍历顺序是根路径在path_argv中列出的顺序,其他所有目录都按照目录中列出的顺序。
fts_read()
fts_read()函数返回一个指向FTSENT结构的指针,该结构描述了层次结构中的文件。至少两次访问目录(可读且不会引起循环),一次访问为预购,一次访问为后购。所有其他文件至少被访问一次。 (目录之间的硬链接不会引起循环,或者符号链接到符号链接可能会导致文件被访问多次或目录被访问两次以上。)
如果已返回层次结构的所有成员,则fts_read()返回NULL并将外部变量errno设置为0。如果发生与层次结构中的文件无关的错误,则fts_read()返回NULL并适当地设置errno。如果发生与返回的文件相关的错误,则返回指向FTSENT结构的指针,并且可能会或可能不会设置errno(请参阅fts_info)。
在相同文件层次结构流上调用fts_close()之后,或者在相同文件层次结构流上调用fts_read()之后,除非它们表示目录类型的文件,否则fts_read()返回的FTSENT结构可能会被覆盖。在这种情况下,直到函数fts_read()返回FTSENT结构后再调用fts_read()之后,它们才会被覆盖。
fts_children()
fts_children()函数返回一个指向FTSENT结构的指针,该结构描述fts_read()最近返回的FTSENT结构表示的目录中文件的以NULL结尾的链接列表中的第一个条目。该列表通过FTSENT结构的fts_link字段进行链接,并由用户指定的比较功能(如果有)进行排序。重复调用fts_children()将重新创建此链接列表。
作为一种特殊情况,如果尚未为层次结构调用fts_read(),则fts_children()将返回一个指针,该指针指向fts_open()指定的逻辑目录中的文件,即fts_open()指定的参数。否则,如果fts_read()最近返回的FTSENT结构不是正在按预定顺序访问的目录,或者该目录不包含任何文件,则fts_children()返回NULL并将errno设置为零。如果发生错误,则fts_children()返回NULL并适当设置errno。
在同一文件层次结构流上调用fts_children(),fts_close()或fts_read()之后,可能会覆盖fts_children()返回的FTSENT结构。
instr参数为零或以下值:
- FTS_NAMEONLY
- 只需要文件名。除fts_name和fts_namelen字段外,未定义返回的结构链接列表中所有字段的内容。
fts_set()
函数fts_set()允许用户应用程序确定流ftsp的文件f的进一步处理。 fts_set()函数成功返回0,如果发生错误则返回-1。
instr参数为0(表示"不执行任何操作")或以下值之一:
- FTS_AGAIN
- 重新访问文件;可以重新访问任何文件类型。下次调用fts_read()将返回引用的文件。届时将重新初始化该结构的fts_stat和fts_info字段,但不会更改其他任何字段。此选项仅对fts_read()中最近返回的文件有意义。正常使用是用于后置目录访问,它使目录及其所有后代都被重新访问(按预定顺序和后置顺序)。
- FTS_FOLLOW
- 引用的文件必须是符号链接。如果引用的文件是fts_read()最近返回的文件,则对fts_read()的下一次调用将返回文件,并重新初始化fts_info和fts_statp字段以反映符号链接的目标而不是符号链接本身。如果文件是fts_children()最近返回的文件之一,则结构的fts_info和fts_statp字段在由fts_read()返回时将反映符号链接的目标,而不是符号链接本身。在任何一种情况下,如果符号链接的目标不存在,则返回结构的字段将保持不变,并且fts_info字段将设置为FTS_SLNONE。
- 如果链接的目标是目录,则完成预排序返回,然后返回其所有后代,然后是后排序返回。
- FTS_SKIP
- 没有访问此文件的后代。该文件可能是fts_children()或fts_read()最近返回的文件之一。
fts_close()
fts_close()函数关闭ftsp引用的文件层次结构流,并将当前目录恢复到调用fts_open()打开ftsp的目录中。 fts_close()函数成功返回0,如果发生错误则返回-1。
错误说明
函数fts_open()可能会失败,并为open(2)和malloc(3)指定的任何错误设置errno。
函数fts_close()可能会失败,并为chdir(2)和close(2)指定的任何错误设置errno。
函数fts_read()和fts_children()可能会失败,并为chdir(2),malloc(3),opendir(3),readdir(3)和stat(2)指定的任何错误设置errno。
此外,fts_children(),fts_open()和fts_set()可能会失败,并按以下方式设置errno:
- EINVAL
- options或instr无效。
版本
从glibc2开始,这些功能在Linux中可用。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
fts_open(),fts_set(),fts_close() | Thread safety | MT-Safe |
fts_read(),fts_children() | Thread safety | MT-Unsafe |
遵循规范
4.4BSD。
BUGS
在2.23之前的glibc版本中,使用LFS API编译程序时(例如,使用-D_FILE_OFFSET_BITS = 64编译时),此手册页中描述的所有API都不安全。
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。