概述
摘要: fcntl函数是Linux系统编程中一个重要的函数,用于对文件描述符进行各种控制操作。本文将详细介绍fcntl函数的原型、各个参数的用法,以及阻塞和非阻塞模式切换的方法,并提供相应的代码示例,帮助读者更好地理解和应用fcntl函数。
介绍
fcntl函数是Linux系统编程中的一个文件控制函数,用于对文件描述符进行各种操作,如文件锁定、文件描述符状态设置等。它的原型如下:
函数原型与参数
#include <fcntl.h>
int fcntl(int fd, int cmd, ...);
fcntl函数接受三个参数:文件描述符fd、控制命令cmd和可选的第三个参数arg。
参数用法
文件描述符fd:需要进行控制的文件描述符。
控制命令cmd:决定了具体的操作。常见的命令有:
F_GETFL:获取文件描述符的状态标志。
F_SETFL:设置文件描述符的状态标志。
F_GETFD:获取文件描述符的文件执行标志。
F_SETFD:设置文件描述符的文件执行标志。
F_SETLK:设置文件锁。
F_GETLK:获取文件锁状态。
可选的第三个参数arg:用于某些控制命令的附加参数,具体取决于cmd的值。
拓展:fcntl改文件属性
fcntl用来改变一个【已经打开】的文件的 访问控制属性
重点掌握两个参数的使用, F_GETFL,F_SETFL
int fcntl(int fd, int cmd, ...)
fd 文件描述符
cmd 命令,决定了后续参数个数
int flgs = fcntl(fd, F_GETFL);
flgs |= O_NONBLOCK
fcntl(fd, F_SETFL, flgs);
获取文件状态: F_GETFL
设置文件状态: F_SETFL
终端文件默认是阻塞读的,这里用fcntl将其更改为非阻塞读
1.#include <unistd.h>
2.#include <fcntl.h>
3.#include <errno.h>
4.#include <stdio.h>
5.#include <stdlib.h>
6.#include <string.h>
7.
8.#define MSG_TRY "try again\n"
9.
10.int main(void)
11.{
12. char buf[10];
13. int flags, n;
14.
15. flags = fcntl(STDIN_FILENO, F_GETFL); //获取stdin属性信息
16. if(flags == -1){
17. perror("fcntl error");
18. exit(1);
19. }
20. flags |= O_NONBLOCK;
21. int ret = fcntl(STDIN_FILENO, F_SETFL, flags);
22. if(ret == -1){
23. perror("fcntl error");
24. exit(1);
25. }
26.
27.tryagain:
28. n = read(STDIN_FILENO, buf, 10);
29. if(n < 0){
30. if(errno != EAGAIN){
31. perror("read /dev/tty");
32. exit(1);
33. }
34. sleep(3);
35. write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
36. goto tryagain;
37. }
38. write(STDOUT_FILENO, buf, n);
39.
40. return 0;
41.}
编译运行,结果如下:
可以看到,是非阻塞读取。
总结
通过详细介绍fcntl函数的原型、参数用法以及阻塞和非阻塞模式切换的方法,我们希望读者能够更好地理解和应用fcntl函数