fcntl函数可以改变已经打开文件的属性
#include <fcntl.h>
int fcntl(int fd,int cmd,.../*int arg*/);
//返回值:若成功,则依赖于cmd;若出错,则返回-1
fcntl函数有以下五种功能。
- 复制一个已有的描述符(cmd=FDUPFD或FDUPFD_CLOEXEC)。
- 获取/设置文件描述符标志(cmd=FGETFD或F_SETFD)。
- 获取/设置文件状态标志(cmd=FGETFL或F_SETFL)。
- 获取/设置异步I/O所有权(cmd=FGETOWN或F_SETOWN)。
- 获取/设置记录锁(cmd=F_GETLK、F_SETLK或F_SETLKW)。
实例:
在修改文件描述符标志时必须谨慎,先要获得现在的标志值,然后按照期望修改它,最后设置新标志值。
不能只是执行FSETFD或F_SETFL命令,这样会关闭以前设置的标志位。
#include <fcntl.h>
#include "apue.h"
/**
* flags are file status flags to turn on
*/
void set_fl(int fd, int flags){
int val;
if((val = fcntl(fd, F_GETFL,0)) < 0){
err_sys("fcntl F_GETFL error");
}
val |= flags;
if(fcntl(fd, F_SETFL, val) < 0){
err_sys("fcntl F_SETFL error");
}
}
如果在图3-5程序的开始处加上下面一行以调用set_fl,则开启了同步写标志。
setfl(STDOUTFILENO,O_SYNC);
这就使每次write都要等待,直至数据已写道磁盘上再返回。在UNIX系统中,通常write只是将数据排入队列,而实际写的磁盘操作可能在以后的某个时刻执行。
而数据库系统则需要使用O_SYNC,这样一来,当它从write返回时就知道数据已确实写到了磁盘上,以免在系统异常时产生数据丢失。
程序运行时,设置O_SYNC标志会增加系统时间和时钟时间。
比较fsync和fdatasync两者都更新文件内容,用了O_SYNC标志,每次写入文件都更新文件内容。
每一种调用的性能依赖很多因素,包括底层操作系统的实现,磁盘驱动器的速度,以及文件系统的类型。