fcntl()系统调用
来源:互联网 发布:软件系统开发评估 编辑:程序博客网 时间:2024/04/28 00:48
五一3天小长假,在家里悠闲度过了。基本没学习,昨天下午回到深圳,研究了一下fcntl()系统调用。
1. 函数介绍
函数fcntl()用于修改某个文件描述符的属性,函数原型为:
#include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
第1个参数fd为待修改属性的文件描述符,第2个参数cmd为对应的操作命令,第3个参数为cmd的参数。
常见的cmd命令有:
F_DUPFD //复制文件描述符,跟dup()函数功能一样F_GETFD //获取文件描述符标志F_SETFD //设置文件描述符标志F_GETFL //获取文件状态F_SETFL //设置文件状态
函数执行失败,将返回-1并设置errno全局变量来指明错误。
不同的cmd其返回值不同: 若是设置文件属性,成功返回0失败返回-1;
若是读取文件属性,成功返回该属性值,失败返回-1。
2. 函数使用
2.1 F_DUPFD赋值文件描述符
fcntl()函数中cmd若使用F_DUPFD命令则是复制文件描述符,返回的值是新的文件描述符,该文件描述符同样指向原文件,具有特点有:
1) 大于或者等于指定的最小可用的文件描述符。”指定”是在函数的第三个参数指定的。
2) 和原文件相同方式的打开文件(包括管道)
3) 两个文件描述符共享一个文件指针
4) 两个文件描述符共享同一文件状态标志
5) 新的文件描述符关联的close-on-exec标志在各execX()函数簇中还是保持打开状态
int main(void){ const char* ptr = "Hello, funtl()\n"; int fd, new_fd; fd = open("tmp.file", O_WRONLY | O_CREAT, 0666); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } //赋值文件描述符,参数3设置为0,那么new_fd为3 new_fd = fcntl(fd, F_DUPFD, 0); printf("fd = %d, new_fd = %d\n", fd, new_fd); printf("write %d bytes to fd\n", write(fd, ptr, strlen(ptr))); printf("write %d bytes to new_fd\n", write(new_fd, ptr, strlen(ptr))); close(fd); close(new_fd); system("cat tmp.file"); return 0;}
运行结果:
2.2 F_GETFD / F_SETFD操作close-on-exec
首先了解close-on-exec是什么?每个文件描述符都有一个close-on-exec标志,这个标志的具体作用是体现在其它进程调用execX()函数簇时,是否关闭在这之前的文件描述符。F_GETFD命令获取文件描述符关联的close-on-exec标志。如果close-on-exec低序位为0,文件将在execX()函数执行期间保持打开状态,否则文件在执行execX()函数期间是关闭的。默认情况下是打开的,则允许在execX()函数簇代码中访问原来打开的文件描述符。
F_SETFL命令用于设置与文件描述符相关的close-on-exec标志,设置的值为fcntl的第3个参数。
若设置为1,即FD_CLOEXEC,
/* for F_[GET|SET]FL */#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
那么子进程的execX()函数簇中不可以使用该文件描述符,代码示例在http://blog.csdn.net/qq_29344757/article/details/70316536#t13讲过。
2.3 F_GETFL / F_SETFD设置文件描述符状态
F_GETFL命令用于获取文件状态标志,F_SETFL将文件状态标志设置为funtl()的第3个参数。也就是说,它不能设置读写属性(O_RDWR、O_WRONLY、O_RDONLY),设置文件状态属性,如阻塞/非阻塞、追加(O_APPEND)。
/* 实验证明: F_SETFD是设置文件的close-on-exec标志 F_SETFD是设置文件状态属性,如阻塞/非阻塞、追加(O_APPEND)*/int pre_test(int flag){ int accmode; accmode = flag & O_ACCMODE; //获取文件的读写属性需要这么操作 if (accmode == O_RDONLY) printf("read only"); else if (accmode == O_WRONLY) printf("write only"); else if (accmode == O_RDWR) printf("read write"); else printf("unknown mode"); if (flag & O_APPEND) printf(", append"); if (flag & O_NONBLOCK) printf(", nonblocking"); printf("\n"); return 0;}int main(int argc, char** argv){ int flag; int fd; fd = open("./tmp.file", O_RDONLY); flag = fcntl(fd, F_GETFL); if (flag < 0) { perror("fcntl"); exit(EXIT_FAILURE); } pre_test(flag); fcntl(fd, F_SETFL, flag | O_NONBLOCK | O_APPEND); flag = fcntl(fd, F_GETFL); pre_test(flag); return 0;}
运行结果:
F_SETFD和F_SETFL存在区别:
F_SETFD仅更改该文件描述符的信息,而F_SETFL则是更改与该文件相关的所有描述符。比如复制了某个文件描述符后,若使用F_SETFD修改close-on-exec标志,那么只是修改该文件描述符信息,若使用F_SETFL修改将修改原文件和拷贝文件描述符的状态信息。
水平有限,上述结论可能还有误,先总结这么多吧,
- fcntl系统调用--转
- fcntl系统调用
- fcntl 系统调用
- fcntl系统调用
- fcntl系统调用
- fcntl系统调用
- fcntl()系统调用
- fcntl()系统函数调用
- linux 系统调用fcntl详解
- 系统调用fcntl 和 ioctl
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- Linux系统调用--fcntl函数详解
- 知识点
- html中提交表单并实现不跳转页面处理返回值
- 【解决】springmvc 前台表单提交数据返回400错误
- ARM学习笔记3
- thinkphp js路径问题
- fcntl()系统调用
- vue写一个图片轮播的组件,在父组件中引用。用到mui。push。concat。vue
- ijkplayer详解使用教程
- Git-小结
- java简单的正则表达式验证邮箱
- 一个有趣的算法题
- requestDisallowInterceptTouchEvent的用法
- neo4j 一些常用的cql
- 319. Bulb Switcher