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

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

其中,操作类型由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:给文件加上进程锁,如果此文件之前已经被加了锁,则一直等待锁被释放。

  接下来看两段代码:

#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>

#define ERR_EXIT(msg) \
  do \
  { \
    perror(msg); \
    exit(-1); \
  } while(0)

int main()
{
  int fd = open("test.dat", O_CREAT | O_RDWR | O_TRUNC, 0644);
  if (fd < 0)
    ERR_EXIT("open file failed");

  struct flock f;
  memset(&f, 0, sizeof(f));
  f.l_type = F_WRLCK;
  f.l_whence = SEEK_SET;
  f.l_start = 0;
  f.l_len = 0;

  if (fcntl(fd, F_SETLK, &f) < 0)
    ERR_EXIT("lock file failed");

  printf("press any key to unlock\n");
  getchar();
  f.l_type = F_UNLCK;
  if (fcntl(fd, F_SETLK, &f) < 0)
    ERR_EXIT("unlock file failed");
  return 0;
}

上述代码实现了加锁和解锁两个操作。

#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>

#define ERR_EXIT(msg) \
  do \
  { \
    perror(msg); \
    exit(-1); \
  } while(0)

void set_flag(int fd, int flags);
void clr_flag(int fd, int flags);

int main()
{
  char buf[1024];
  set_flag(0, O_NONBLOCK);
  int ret = read(0, buf, 1024);
  if (ret < 0)
    ERR_EXIT("read failed");
  return 0;
}

void set_flag(int fd, int flags)
{
  int val = fcntl(fd, F_GETFL, 0);
  if (val < 0)
    ERR_EXIT("get flag failed");
  val |= flags;
  if (fcntl(fd, F_SETFL, val) < 0)
    ERR_EXIT("set flag failed");
}
void clr_flag(int fd, int flags)
{
  int val = fcntl(fd, F_GETFL, 0);
  if (val < 0)
    ERR_EXIT("get flag failed");
  val &= ~flags;
  if (fcntl(fd, F_SETFL, val) < 0)
    ERR_EXIT("set flag failed");
}

其中set_flag设置文件状态标识,clr_flag清除文件状态标识。main函数中将stdout设置成非阻塞,所以执行read时,不等待用户输入而直接返回错误。

linux c编程之fcntl

linux c编程之fcntl的更多相关文章

  1. linux网络编程之shutdown() 与 close()函数详解

    linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这 ...

  2. Linux应用编程之lseek详解

    Linux应用编程之lseek详解 1.lseek函数介绍 (1).文件指针:当我们要对一个文件进行读写时,一定要先打开这个文件,所以我们读写的所有文件都是动态文件.动态文件在内存中的形态就是文件流的 ...

  3. linux C编程之makefile

    目的:       基本掌握了 make 的用法,能在Linux系统上编程.环境:       Linux系统,或者有一台Linux服务器,通过终端连接.一句话:有Linux编译环境.准备:      ...

  4. linux网络编程之IO模型

    本文转自作者:huangguisu 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步:      所谓 ...

  5. linux网络编程之socket编程(十六)

    继续学习socket编程,今天的内容会有些难以理解,一步步来分解,也就不难了,正入正题: 实际上sockpair有点像之前linux系统编程中学习的pipe匿名管道,匿名管道它是半双工的,只能用于亲缘 ...

  6. (十)Linux 网络编程之ioctl函数

    1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...

  7. (ubuntu)linux C编程之sleep()和usleep()的使用和区别

    ### 函数名: sleep 头文件: #include <windows.h> // 在VC中使用带上头文件 #include <unistd.h> // 在gcc编译器中, ...

  8. linux socket编程之TCP与UDP

    转:http://blog.csdn.net/gaoxin1076/article/details/7262482 TCP/IP协议叫做传输控制/网际协议,又叫网络通信协议 TCP/IP虽然叫传输控制 ...

  9. Linux内核模块编程之Helloworld(初级)

    注意printk那里,KERN_ALERT和打印消息之间是没有逗号的,搞得劳资查了半天才发现一直没有提示信息的原因 #include <linux/init.h> #include < ...

随机推荐

  1. MyBatis批量修改操作

    1.需求 后台管理页面,查询频道列表,需要批量修改频道的状态,批量上线和下线 2.MyBatis配置 这是mysql的配置,注意需要加上&allowMultiQueries=true配置 jd ...

  2. 一天一个Linux命令--dhclient

    dhclient -r #用于释放ip地址2 dhclient #获取IP地址 主要针对只有命令行的Linux机器,临时改变了网络环境,事先手动设置的ip地址 看一下自带的解释 root@ubuntu ...

  3. CentOS 6.2 中文

    在虚拟机里面安装好centos6.2之后,默认是英文!   对于命令行操作无所谓啦,但是如果想看界面,就不是很适应!   修改方法如下:   1.用root登录系统,密码为创建虚拟机时候的密码.创建虚 ...

  4. 在Visual Studio 2017上配置并使用OpenGL

    在Visual Studio 2017上配置并使用OpenGL 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 首先在Windows下安装Visual ...

  5. 基于Angular和Spring WebFlux做个小Demo

    前言 随着Spring Boot2.0正式发布,Spring WebFlux正式来到了Spring Boot大家族里面.由于Spring WebFlux可以通过更少的线程去实现更高的并发和使用更少的硬 ...

  6. Java使用volatile实现多线程输出ABC共10次

    问题 有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C.要求,同时启动三个线程, 按顺序输出ABC, 循环10次. 今天在写多线程的时候找例子,见到了这样一个题,觉得不难,但是在网 ...

  7. 二叉搜索树的最近公共祖先的golang实现

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...

  8. Use of Recv-Q and Send-Q

    From my man page: Recv-Q Established: The count of bytes not copied by the user program connected to ...

  9. js 设备判断(移动端pc端 安卓ios 微信)

    苹果安卓判断 $(function () { var u = navigator.userAgent, app = navigator.appVersion; var isAndroid = u.in ...

  10. UVALive - 3713 - Astronauts(图论——2-SAT)

    Problem   UVALive - 3713 - Astronauts Time Limit: 3000 mSec Problem Description Input The input cont ...