Linux高级I/O函数 fcntl()

fcntl(file control)提供对文件描述符的各种控制操作。另一个常见控制文件描述符的系统调用是ioctl,提供更多控制。
fcntl提供常用属性和行为的控制,是POSIX规定的首选方法。

本文对fcntl常用操作进行一个简要汇总。

fcntl 声明

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

参数
fd 被操作的文件描述符;
cmd 指定执行何种类型的操作。根据操作类型不同,可能还要第三个可选参数arg。

返回值
成功时,不同的cmd有不同的含义;失败时,返回-1,错误保存至errno。

fcntl功能汇总

操作分类 操作 含义 第三个参数类型 成功时的返回值
复制fd F_DUPFD 创建一个新fd,值 >= arg long 新创建的fd值
F_DUPFD_CLOEXEC 与F_DUPFD类似,不过创建fd同时,设置其close-on-exec标志 long 新创建的fd值
获取和设置fd的标志 F_GETFD 获取fd的标志,如close-on-exec标志 fd标志
F_SETFD 设置fd的标志 long 0
获取和设置fd状态标志 F_GETFL 获取fd的状态标志,包括由open系统调用设置的
标志(O_APPEND, O_CREAT等)和访问模式
(O_RDONLY、O_WRONLY、O_RDWR)
void fd状态标志
F_SETFL 设置fd的状态标志,但部分标志不能被修改(如访问模式标志) long 0
管理信号 F_GETOWN 获得SIGIO和SIGURG信号的宿主进程的PID或进程组的组ID 信号的宿主进程的PID或进程组的组ID
F_SETOWN 设定SIGIO和SIGURG信号的宿主进程的PID或进程组的组ID long 0
F_GETSIG 获取当应用程序被通知fd可读或可写时,是哪个信号通知该事件的 信号值,0表示SIGIO
F_SETSIG 设置当fd可读或可写时,系统应该触发哪个信号来通知应用程序 long 0
操作管道容量 F_SETPIPE_SZ 设置由fd指定的管道容量,/proc/sys/fs/pipe-size-max
内核参数指定了fcntl能设置的管道容量的上限
long 0
F_GETPIPE_SZ 获取由fd指定的管道容量 管道容量

示例:最常用的将fd设为nonblocking

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

参考

《Linux高性能服务器编程》

posted @ 2022-04-30 18:53  明明1109  阅读(330)  评论(0编辑  收藏  举报