Linux中的高级IO函数(三)fcntl

Linux提供了很多高级的I/O函数。它们并不像Linux基础I/O函数(比如open和read)那么常用(编写内核模块时一般要实现这些I/O函数),但在特定的条件下却表现出优秀的性能。这些函数大致分为三类:

用于创建文件描述符的函数,包括pipe、socketpair、dup/dup2函数。
用于读写数据的函数,包括readv/writev、sendfile、mmap/munmap、splice和tee函数。
用于控制I/O行为和属性的函数,包括fcntl函数。

本节接着介绍第三类

一、fcntl函数

fcntl函数全称是 file control 。该函数提供了对文件描述符的各种控制操作。另外一个常见的控制文件描述符属性和行为的系统调用是ioctl,而且ioctlfcntl能够执行更多的控制。但是,对于控制文件描述符常用的属性和行为,fcntl函数是由POSIX规范指定的首选方法。

#include <fcntl.h>

int fcntl(int fd, int cmd,  ...);
  • fd参数是被操作的文件描述符

  • cmd参数指定执行何种类型的操作

下面是一些常见的操作

cmd 含义 第三个参数类型 成功时返回值
F_DUPFD 复制文件描述符 int 复制的新文件描述符
F_GETFD 获取文件描述符标志 文件描述符标志位(整数)
F_SETFD 设置文件描述符标志 int 0(成功)或 -1(失败)
F_GETFL 获取文件状态标志 文件状态标志位(整数)
F_SETFL 设置文件状态标志 int 0(成功)或 -1(失败)
F_GETLK 获取记录锁 struct flock * 0(无冲突)或 -1(失败)
F_SETLK 设置记录锁 const struct flock * 0(成功)或 -1(失败)
F_SETLKW 设置记录锁(阻塞版本) const struct flock * 0(成功)或 -1(失败)
F_GETOWN 获取异步I/O所有权 所有权的进程ID(整数)
F_SETOWN 设置异步I/O所有权 pid_t 0(成功)或 -1(失败)
F_GETLK64 获取记录锁(64位版本) struct flock64 * 0(无冲突)或 -1(失败)
F_SETLK64 设置记录锁(64位版本) const struct flock64 * 0(成功)或 -1(失败)
F_SETLKW64 设置记录锁(阻塞版本,64位版本) const struct flock64 * 0(成功)或 -1(失败)
F_GETSIG 获取信号 信号值(整数)
F_SETSIG 设置信号 int 0(成功)或 -1(失败)
F_GETLEASE 获取文件租约状态 租约状态(整数)
F_SETLEASE 设置文件租约 int 0(成功)或 -1(失败)
F_NOTIFY 监视文件状态变化 int 0(成功)或 -1(失败)
F_GETPIPE_SZ 获取管道容量 管道容量(整数)
F_SETPIPE_SZ 设置管道容量 int 0(成功)或 -1(失败)
F_GET_SEALS 获取文件封印状态 文件封印状态(整数)
F_ADD_SEALS 添加文件封印 unsigned int 0(成功)或 -1(失败)
F_GET_RW_HINT 获取读写优化提示 读写优化提示(整数)
F_SET_RW_HINT 设置读写优化提示 unsigned int 0(成功)或 -1(失败)
F_GET_FILE_RW_HINT 获取文件读写优化提示 读写优化提示(整数)
F_SET_FILE_RW_HINT 设置文件读写优化提示 unsigned int 0(成功)或 -1(失败)
F_GETLKPID 获取记录锁并返回占有者的进程ID struct flock * 占有者的进程ID(整数)或 -1(失败)
F_OFD_GETLK 获取OFD记录锁 struct flock * 0(无冲突)或 -1(失败)
F_OFD_SETLK 设置OFD记录锁 const struct flock * 0(成功)或 -1(失败)
F_OFD_SETLKW 设置OFD记录锁(阻塞版本) const struct flock * 0(成功)或 -1(失败)

在常见的编程中,fcntl函数通常用来将一个文件描述符设置为非阻塞的。

int setnonblocking(int fd) {
	/* 获取文件描述符旧的状态标志 */
    int old_option=fcntl(fd,F_GETFL);
    /* 设置非阻塞标志 */
    int new_option=old_option|O_NONBLOCK;
    /* 写入设置 */
    fcntl(fd,F_SETFL,new_option);
    /* 返回文件描述符旧的状态标志,以便日后恢复该状态标志 */
    return old_option;
}

此外,SIGIOSIGURG这两个信号与其他Linux信号不同,它们必须与某个文件描述符相关联方可使用:当被关联的文件描述符可读或可写时,系统将触发SIGIO信号;当被关联的文件描述符(而且必须是一个socket)上有带外数据可读时,系统将触发SIGURG信号。将信号和文件描述符关联的方法,就是使用fcntl函数为目标文件描述符指定宿主进程或进程组,那么被指定的宿主进程或进程组将捕获这两个信号。

相关推荐

  1. Linux高级IO函数fcntl

    2024-04-24 11:32:02       35 阅读
  2. Linux高级权限

    2024-04-24 11:32:02       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-24 11:32:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-24 11:32:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-24 11:32:02       87 阅读
  4. Python语言-面向对象

    2024-04-24 11:32:02       96 阅读

热门阅读

  1. windows ubuntu linux三剑客,sed awk grep 篇,1.

    2024-04-24 11:32:02       29 阅读
  2. 深入浅出MySQL-01-【SQL基础】

    2024-04-24 11:32:02       30 阅读
  3. 停车场管理系统(栈和队列的实现和应用)(cpp)

    2024-04-24 11:32:02       37 阅读
  4. 各类数据引擎指定schema或者数据库

    2024-04-24 11:32:02       32 阅读
  5. linux中新建一个超级管理员

    2024-04-24 11:32:02       39 阅读
  6. vue-json-editor

    2024-04-24 11:32:02       36 阅读
  7. map_or

    2024-04-24 11:32:02       32 阅读
  8. 如何对同一docker注册表使用多个身份验证/登录

    2024-04-24 11:32:02       31 阅读