fcntl()应用

来源:互联网 发布:平面设计手机作图软件 编辑:程序博客网 时间:2024/06/13 00:04



fcntl函数(改变打开文件的属性):(用man fcntl看fcntl的帮助文档)

#include<fcntl.h>//这个头文件在/usr/include/bits/fcntl.h
#include <unistd.h>
#include <sys/types.h>
int fcntl(int filedes,int cmd,...);
上边一行等价于:
int fcntl(int filedes,int cmd,long arg);
int fcntl(int filedes,int cmd,struct flock *lock);
返回:若成功则依赖与cmd,若出错为-1.
1)fcntl函数可以改变已经打开文件的属性。
2)fcntl函数有5中功能:
   a复制一个现存的文件描述符,新文件描述符作为文件的返回值(cmd = F_DUPFD)
   b获得/设置文件描述符标记,对应于filedes的文件描述符标志作为函数返回值。(cmd =F_GETFD或F_SETFD) 
   c获得/设置文件状态标志,对应于filedes的文件状态标志作为函数返回值(cmd = F_SETFL或F_GETFL)
   d 获得/设置异步I/O所有权(cmd =F_GETOWN或F_SETOWN)
   e 获得/设置记录锁(cmd =F_GETLK,F_SETLK或F_SETLKW) 
 
1.cmd值为F_DUPFD时
返回一个如下的文件描述符:
1)最小值大于或等于arg的一个可用的文件描述符。
2)返回的文件描述符与filedes指向相同的文件表项,他们具有相同的偏移量、文件状态标志等
3)与新的文件描述符结合在一起的close-on-exec标志被设置成交叉式访问execve(2)的系统调用

所以:dup(oldfd) <==>fcntl(oldfd,F_DUPFD,0)
     dup2(oldfd,newfd) <==>close(newfd);fcntl(oldfd,F_DUPFD,newfd);

2.cmd值为F_GETFD或F_SETFD时(先看看进程部分的exec函数)
F_GETFD取得与文件描述符fd联合的close-on-exec标志,类似FD_CLOEXEC。如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保持交叉式访问exec(),否则如果通过exec运行的话,文件将被关闭(arg被忽略)看看后面的exec函数(关于进程的)
F_SETFD设置close-on-exec标志,该标志以参数arg的FD_CLOEXEC位来决定,应当了解很多现存的涉及文件描述符标志的程序并不使用常数FD_CLOEXEC,而将此标志设置为0(系统默认,在exec时不关闭)或1(在exec时关闭)
例如:
fcntl(fd,F_SETFD,FD_CLOEXEC)
这里设置为FD_CLOEXEC表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程
fcntl(fd,F_SETFD,0)
表示本fd将保持打开状态复制到exec创建的新进程中。
注意:在修改文件描述符标志或文件状态标志值必须谨慎,下药取得现在的标志值,然后按照希望修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。

3.cmd值为F_SETFL或F_GETFL时(文件状态标识说明看/usr/include/bits/fcntl.h和/usr/src/linu../include/linux/sched.h用vi-t来查看)src/flag.c   include/io.h,src/io.c,src/write.c
F_GETFL 取得文件fd的状态标志(arg忽略,即没有),这个状态标志就是open是的oflag
F_SETFL 设置文件的状态标志
例如:
openflag = fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,opennewflog);
注意:
1)fcntl的文件状态有7个:O_RDONLY,O_WRONLY,O_RDWR,O_NONBLOCK,O_APPEND,O_SYNC(异步I/O),O_ASYNC(等待写完成),可以更改的标志是O_APPEND,O_NONBLOCK,O_SYNC,O_ASYNC。(没有O_EXEC等其他的)
O_NONBLOCK:非阻塞I/O,如果read(2)调用没有可读的数据,或者如果write(2)操作将阻塞,则read或write调用将返回-1和EAGAIN错误。
O_APPEND:强制每次写(write)操作都将添加在文件大的末尾,相当于open(2)的O_APPEND标志。
O_DIRECT:最小化或去掉reading和writing的缓存影响。系统将企图避免缓存你的读或写的数据,如果不能避免缓存,那么它将最小化已经被缓存了的数据造成的影响。如果这个标志用的不够好,将大大降低性能。
O_ASYNC:当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可读的时候。
2)看看fcntl.h文件便可知道,文件的oflag各是什么样的值,有个特殊的O_RDONLY(0),O_WRONLY(1),O_RDWR(2),在二进制中不是各占以为,所以这三个值得设置和获取用屏蔽字O_ACCMODE.
3)对文件状态标志的一些操作:
a flag = fcntl(fd,F_GETFL);
b 判定:若判定O_RDONLY,O_WRONLY,O_RDWR,则用flag&O_ACCMODE;
       若判定O_APPEND(O_NONBLOCK,O_SYNC,O_ASYNC),则用flag&O_APPEND等;例如:if(flag&O_APPEND){}。
c 添加:flag|O_APPEND(O_NONBLOCK/O_SYNC/O_ASYNC)
d 删除:flag&=(~O_APPEND)
0 0
原创粉丝点击