文件属性fcntl()函数
fcntl()函数用于获得和改变已经打开文件的性质
1. fcntl()函数介绍
fcntl()函数向打开的文件fd发送命令,更改其属性。
#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
如果操作成功,其返回值依赖于cmd,如果出错返回值为-1。
下面4个命令有特殊的返回值:
1. F_DUPFD 返回值为新的文件描述符
2. F_GETFD 返回值为获得的相应标志
3. F_GETFL 返回值为文件描述符的状态标志
4. F_GETOWN 返回值如果为正数则是进程ID号,如果为负数则是进程组ID号。
函数fcntl()的功能分为以下6类:
☀复制文件描述符(cmd=F_DUPFD);
☀获得/设置文件描述符(cmd=F_GETFD或者F_SETFD);
☀获得/设置文件状态值(cmd=F_GETFD或者F_SETFL);
☀获得/设置信号发送对象(cmd=F_GETOWN、F_SETOWN、F_GETSIG或者F_SETSIG);
☀获得/设置记录锁(cmd=F_GETLK、F_SETLK或者F_SETLKW);
☀获取/设置文件租约(cmd=F_GETLEASE或者F_SETLEASE)。
描述符介绍:
F_DUPFD:命令用于复制文件描述符fd,获得的新文件描述符作为函数返回,获得的文件描述符是尚未使用的文件描述符中大于或等于第3个参数值中的最小值。(duplicate 复制)
F_GETFD:获得文件描述符。
F_SETFD:设置文件描述符。
F_GETFL:标志获得文件描述符fd的文件状态标志,标志的含义在下表列出:
文件状态值 | 含义 |
O_RDONLY | 只读 |
O_WRONLY | 只写 |
O_RDWR | 读写 |
O_APPEND | 写入时添加至文件末尾 |
O_NONBLOCK | 非阻塞方式(Non-blocking 非阻塞) |
O_SYNC | 同步方式 |
O_ASYNC | 异步方式 |
O_RDONLY、O_WRONLY和O_RDWR这三种存取方式并不是各占1位,这3个值分别为0、1、2,要正确地获取它们的值,只能用O_ACCMODE获得存取位,然后与这三种方式比较。
2. F_GETFL的例子
下面的代码为使用F_GETFL的实例,获得标准输入的存取方式,并打印出来:
将代码存入文件fcntl_01.c中,编译并运行文件,获得表述输入的状态,说明标准输入是可读写的:
3. F_SETFL的例子
F_SETFL设置文件状态标志的值,此时用到了第3个参数。其中O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_EXCL、O_NOCTTY 和 O_TRUNC 不受影响,可以更改的几个标志是O_APPEND、O_ASYNC、O_SYNC、O_DIRECT、O_NOATIME 和 O_NONBLOCK。
如下代码为修改文件状态值的一个实例,在文本文件test.txt中的内容是 “1234567890abcdefg”。打开文件test.txt时设置为O_RDWR,此时文件的偏移量位于文件 开头,修改状态值的时候增加O_APPEND项,此时文件的偏移量移到文件末尾,写入字符串FCNTL,然后关闭文件。
创建fcntl_02.c文件,将代码写入其中:
编译此文件:
没有运行fcntl_02之前,test.txt文件中的内容如下所示:
运行fcntl_02,并检查test.txt文件的内容:
可见,修改状态后的flags=fcntl(fd,F_SETFL,&flags);函数起了作用。文件的状态已经增加了O_APPEND的属性,文件的偏移量发生了变化,移到了文件test.txt的末尾。
4. F_GETOWN的例子
F_GETOWN获得接收信号SIGIO和SIGIURG信号的进程ID或进程组ID。例如如下代码得到接收信号的进程ID号。
5. F_SETOWN的例子
F_SETOWN用于接收信号SIGIO和SIGURG信号的进程ID或者进程组ID。参数arg为正式设置接收信号的进程ID,arg的值为负值时设置接收信号的进程组ID为arg绝对值。下面的代码将文件test.txt的信号接收设置给进程10000。