Linux fcntl函数

fcntl函数

读法:file control函数

作用:复制文件描述符、设置/获取文件的状态标志

cpp 复制代码
int fcntl(int fd, int cmd, ... /* arg */ )

fd是文件描述符,cmd是命令(定义的宏),... 表示可变的参数(可有可不有)

cpp 复制代码
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、...

总结:

cpp 复制代码
#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_NONBLOCK
            O_APPEND 表示追加数据
            O_NONBLOK 设置成非阻塞
    
    阻塞和非阻塞:描述的是函数调用的行为。
    阻塞函数:调用add函数,进程被发起,并且得到结果之后才会返回。比如终端等待你输入的状态
    非阻塞函数:调用函数时立马就能返回,不会阻塞当前的进程。比如输入命令后终端立马执行。

测试:

cpp 复制代码
#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.修改或者获取文件状态flag
    int fd = open("1.txt", O_RDWR); // 这里是RDWR,不能是只有读权限RDONLY,O_APPEND只是往后面追加
    if(fd == -1) {
        perror("open");
        return -1;
    }
    
    // 获取文件描述符状态flag
    int 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_RDWR
    if(ret == -1) {
        perror("fcntl");
        return -1;
    }

    char * str = "nihao";
    write(fd, str, strlen(str));

    close(fd);

    return 0;
}

运行前后:

cpp 复制代码
1
1nihao
相关推荐
2601_958320572 分钟前
【详细版教程】Windows/macOS/Linux 安装 OpenClaw 2.6.6 指南(包含安装包)
linux·运维·windows·macos·小龙虾·open claw一键安装
霜落花轻扬5 分钟前
在 Rails 中指定端口和 IP 地址
服务器·ruby on rails
ximu_polaris7 分钟前
设计模式(C++)-行为型模式-解释器模式
c++·设计模式·解释器模式
HackTwoHub8 分钟前
可视化未授权访问批量探测工具、支持批量目标、并发扫描、SOCKS5 全局代理、CSV 导出
linux·windows·macos·网络安全·网络攻击模型
安当加密18 分钟前
Spring Boot应用接入国产安当凭据管理系统SMS Starter实战(附源码)
java·spring boot·后端
2401_8971905521 分钟前
【C++高阶系列】告别内查找局限:基于磁盘 I/O 视角的 B 树深度剖析与 C++ 泛型实现!
java·c++·算法
一只专注api接口开发的技术猿22 分钟前
京东商品实时监控选品实战:用 Open Claw API 快速搭建自动化工具
运维·数据库·自动化
ACP广源盛1392462567323 分钟前
磐石 100 :IX6012 :ASM1812@ACP#国产 PCIe 2.0 交换芯片,轻量级算力扩展应用分享
大数据·linux·运维·网络·人工智能·嵌入式硬件·电脑
树下水月23 分钟前
Easyswoole 框架session在高并发/频繁请求下数据丢失问题记录
java·后端·spring
H Journey25 分钟前
网络编程:服务器监听+非阻塞设置
服务器·网络·服务器监听+非阻塞设置