文件I/O之fcntl函数


fcntl函数可以改变已打开的文件的性质。

#include <fcntl.h>
 fcntl(  filedes,  cmd, ... -

在本节的各实例中,第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但是在说明记录锁时,第三个参数则是指向一个结构的指针。

fcntl函数有5种功能:

(1)复制一个现有的描述符(cmd = F_DUPFD )。

(2)获得/设置文件描述符标记(cmd = F_GETFD或F_SETFD)。

(3)获得/设置文件状态标志(cmd = F_GETFL或F_SETFL)。

(4)获得/设置异步I/O所有权(cmd = F_GETOWN或F_SETOWN)。

(5)获得/设置记录锁(cmd = F_GETLK、F_SETLK或F_SETLKW)。

我们先说明这10种cmd值得前7种(后3种,在谈记录锁时说明)。我们将涉及与进程表项中各文件描述符相关联的文件描述符标志,以及每个文件表项中的文件状态标志。

F_DUPFD         复制文件描述符filedes。新文件描述符作为函数值返回。它是尚未打开的各描述符中大于或等于第三个参数值(取为整型值)中各值的最小值。新描述符与filedes共享同一文件表项。但是,新描述符有它自己的一套文件描述符标志,其FD_CLOEXEC文件描述符标志被清除(这表示该描述符在通过一个exec时仍保持有效)。

F_GETFD         对应于filedes的文件描述符标志作为函数值返回。当前只定义了一个文件描述符标志FD_CLOEXEC。

F_SETFD         对于filedes设置文件描述符标志。新标志值按第三个参数(取为整型值)设置。

注:应当了解很多现有的涉及文件描述符标志的程序并不使用常量FD_CLOEXEC,而是将此标志设置为0(系统默认,在exec时不关闭)或1(在exec时关闭)。

F_GETFL         对应于filedes的文件状态标志作为函数值返回。文件状态标志如下表3-3:(表3-3中的各个标志,除了三个访问方式标志(O_RDONLY、O_WRONLY以及O_RDWR)不各占一位,其他标志分别占文件状态标志的一个bit位)

<fcntl.h> argc, *(argc != ((val = fcntl(atoi(argv[]), F_GETFL, )) < , atoi(argv[(val &(val &(val & defined(O_SYNC) (val & !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) (val &

注意,我们使用了功能测试宏_POSIX_C_SOURCE,并且条件编译了POSIX.1中没有定义的文件访问标志。

在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现有的标志值,然后根据需要修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。

程序清单3-5 对一个文件描述符打开一个或多个文件状态标志

[root@localhost apue]# cat prog3-<fcntl.h>

 fd,  flags) ((val = fcntl(fd, F_GETFL, )) < |= flags;   

        (fcntl(fd, F_SETFL, val) < 

如果将中间的一条语句改为:

val &= ~flags;    

就构成另一个函数,我们称其为clr_fl。

比较fsync和fdatasync与O_SYNC标志,fsync和fdatasync在我们需要时更新文件内容,O_SYNC标志则在我们每次写至文件时更新文件内容。

fcntl的必要性:我们的程序在一个描述符(标准输出)上进行操作,但是根本不知道由shell打开的相应的文件名。因为这是shell打开的,于是不能在打开时,按我们的要求设置O_SYNC标志。fcntl则允许仅知道打开文件描述符时可以修改其性质。

相关内容