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高性能服务器编程》