fcntl函数
读法:file control函数
作用:复制文件描述符、设置/获取文件的状态标志
int fcntl(int fd, int cmd, ... /* arg */ )
fd是文件描述符,cmd是命令(定义的宏),… 表示可变的参数(可有可不有)
man 2 fcntl
DESCRIPTION:
fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.
1、Duplicating a file descriptor 复制文件描述符
-
F_DUPFD (int)
Duplicate the file descriptor fd using the lowest-numbered available file descriptor greater than or equal to arg. This is different from dup2(2), which uses exactly the file descriptor specified. (dup2复制指定的fd,而F_DUPFD用的是lowerst)On success, the new file descriptor is returned. -
F_DUPFD_CLOEXEC (int; since Linux 2.6.24)
2、 File descriptor flags 文件描述标志
The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is set, the file descriptor will automatically be closed during a successful execve(2). (If the execve(2) fails, the file descriptor is left open.) If the FD_CLOEXEC bit is not set, the file descriptor will remain open across an execve(2).
-
F_GETFD (void)
-
F_SETFD (int)
3、 File status flags 文件状态标志
Each open file description has certain associated status flags, initialized by open(2) and possibly modified by fcntl(). Duplicated file descriptors (made with dup(2), fcntl(F_DUPFD), fork(2), etc.) refer to the same open file description, and thus share the same file status flags.
- F_GETFL (void) 获取指定的文件描述符文件状态flag
Return (as the function result) the file access mode and the file status flags; arg is ignored.
- F_SETFL (int) 设置文件描述符文件状态flag
Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On Linux, this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags. It is not possible to change the O_DSYNC and O_SYNC flags.
4、…
总结:
#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ...);
参数:fd : 表示需要操作的文件描述符cmd: 表示对文件描述符进行如何操作- F_DUPFD : 复制文件描述符,复制的是第一个参数fd,得到一个新的文件描述符(返回值)int ret = fcntl(fd, F_DUPFD);- F_GETFL : 获取指定的文件描述符文件状态flag获取的flag和我们通过open函数传递的flag是一个东西。- F_SETFL : 设置文件描述符文件状态flag必选项:O_RDONLY, O_WRONLY, O_RDWR 不可以被修改可选性:O_APPEND, O_NONBLOCKO_APPEND 表示追加数据O_NONBLOK 设置成非阻塞阻塞和非阻塞:描述的是函数调用的行为。阻塞函数:调用add函数,进程被发起,并且得到结果之后才会返回。比如终端等待你输入的状态非阻塞函数:调用函数时立马就能返回,不会阻塞当前的进程。比如输入命令后终端立马执行。
测试:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>int main() {// 1.复制文件描述符// int fd = open("1.txt", O_RDONLY);// int ret = fcntl(fd, F_DUPFD); //复制描述符// 2.修改或者获取文件状态flagint fd = open("1.txt", O_RDWR); // 这里是RDWR,不能是只有读权限RDONLY,O_APPEND只是往后面追加if(fd == -1) {perror("open");return -1;}// 获取文件描述符状态flagint flag = fcntl(fd, F_GETFL);if(flag == -1) {perror("fcntl");return -1;}flag |= O_APPEND; // flag = flag | O_APPEND 在原先flag基础上加入O_APPEND// 修改文件描述符状态的flag,给flag加入O_APPEND这个标记int ret = fcntl(fd, F_SETFL, flag); //flag不能直接写O_APPEND,会直接覆盖掉用来的O_RDWRif(ret == -1) {perror("fcntl");return -1;}char * str = "nihao";write(fd, str, strlen(str));close(fd);return 0;
}
运行前后:
1
1nihao