Article Directory
overview
Abstract: The fcntl function is an important function in Linux system programming, which is used to perform various control operations on file descriptors. This article will introduce in detail the prototype of the fcntl function, the usage of each parameter, and the method of switching between blocking and non-blocking modes, and provide corresponding code examples to help readers better understand and apply the fcntl function.
introduce
The fcntl function is a file control function in Linux system programming, which is used to perform various operations on file descriptors, such as file locking, file descriptor status settings, etc. Its prototype is as follows:
Function Prototype and Parameters
#include <fcntl.h>
int fcntl(int fd, int cmd, ...);
The fcntl function accepts three parameters: the file descriptor fd, the control command cmd, and an optional third parameter arg.
Parameter usage
File descriptor fd: The file descriptor that needs to be controlled.
Control command cmd: determines the specific operation. Common commands are:
F_GETFL: Get the status flag of the file descriptor.
F_SETFL: Set the status flag of the file descriptor.
F_GETFD: Get the file execution flag of the file descriptor.
F_SETFD: Set the file execution flag of the file descriptor.
F_SETLK: Set file lock.
F_GETLK: Get the file lock status.
Optional third argument arg: Additional arguments for some control commands, depending on the value of cmd.
Expansion: fcntl changes file attributes
fcntl is used to change the access control attribute of a [already opened] file
Focus on the use of two parameters, F_GETFL, F_SETFL
int fcntl(int fd, int cmd, ...)
The fd file descriptor
cmd command determines the number of subsequent parameters
int flgs = fcntl(fd, F_GETFL);
flgs |= O_NONBLOCK
fcntl(fd, F_SETFL, flgs);
获取文件状态: F_GETFL
设置文件状态: F_SETFL
Terminal files are blocked for reading by default, here use fcntl to change it to non-blocking for reading
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.}
Compile and run, the result is as follows:
As you can see, it is a non-blocking read.
Summarize
By introducing in detail the prototype of the fcntl function, the usage of parameters, and the method of switching between blocking and non-blocking modes, we hope readers can better understand and apply the fcntl function