Linux系统编程——fcntl

fcntl可实现对指定文件描述符的各种操作,其函数原型如下:

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

头文件

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

操作类型由cmd决定,cmd的取值如下:

  • F_DUPFD:复制文件描述符
  • F_DUPFD_CLOEXEC:复制文件描述符,新文件描述符被设置了close-on-exec
  • F_GETFD:读取文件描述标识
  • F_SETFD:设置文件描述标识
  • F_GETFL:读取文件状态标识
  • F_SETFL:设置文件状态标识
  • F_GETLK:如果已经被加锁,返回该锁的数据结构。如果没有被加锁,将l_type设置为F_UNLCK
  • F_SETLK:给文件加上进程锁
  • F_SETLKW:给文件加上进程锁,如果此文件之前已经被加了锁,则一直等待锁被释放。

下面举个例子:

我们知道如果read没有读到数据会阻塞,但加入NONBLOCK描述符后就不会阻塞

read_stdin.c

#include <func.h>

void changeNonblock(int fd){
    int status = fcntl(fd, F_GETFL);//先用F_GETFL拿出原有属性
    status = status|O_NONBLOCK;//再加入非阻塞属性
    fcntl(fd, F_SETFL, status);//重置属性
}

int main()
{
    sleep(5);
    char buf[128] = {0};
    int ret;
    changeNonblock(0);
    ret = read(STDIN_FILENO, buf, sizeof(buf));
    printf("ret = %d, buf = %s\n", ret, buf);
    return 0;
}

1556453896542

在输入hello后过了几秒(五秒内),打印出结果并退出。

另外如果想清空所有文件描述符可以和自己的非按位与:

#include <func.h>

void changeNonblock(int fd){
    int status = fcntl(fd, F_GETFL);
    status = status|O_NONBLOCK;
    fcntl(fd, F_SETFL, status);
}

void clr_flag(int fd){
    int status = fcntl(fd, F_GETFL);
    status &= ~status;//按位与清空文件描述符
    fcntl(fd, F_SETFL, status);
}

int main()
{
    //sleep(5);
    char buf[128] = {0};
    int ret;
    //changeNonblock(0);
    clr_flag(0); 
    ret = read(0, buf, sizeof(buf));
    printf("ret = %d, buf = %s\n", ret, buf);
    return 0;
}
posted @ 2019-04-28 20:23  Mered1th  阅读(210)  评论(0编辑  收藏  举报