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. MongoDB 3.6版本关于bind_ip设置

    2017年下半年新发布的MongoDB 3.6版本在安全性上做了很大提升,主要归结为两点: 1.将将bind_ip 默认值修改为了localhost: 2. 在db.createUser()和 db. ...

  2. 【原】无脑操作:eclipse创建maven工程时,如何修改默认JDK版本?

    问题描述:eclipse建立maven项目时,JDK版本默认是1.5,想创建时默认版本设置为1.8,如何修改? 解决方案: 找到本机maven仓库存放位置,比如:${user.home}/.m2/路径 ...

  3. 【原】Java学习笔记018 - 面向对象

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 继承关系的子类可以 ...

  4. Camera Binning Mode

    Camera Binning Mode:像素合并模式,将相邻的像素单元电荷通过物理的方法叠加在一起作为一个像素输出信号: 水平方向Binning:  同列相邻行的电荷叠加 垂直方向Binning:   ...

  5. 什么是tomcat集群?

    什么是tomcat集群? 利用nginx对请求进行分流,将请求分配给不同的tomcat去处理,减少每个tomcat的负载量,提高服务器的响应速度. 目标 实现高性能负载均衡的tomcat集群. 工具 ...

  6. python文件上传

    1.前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  7. java.util.NoSuchElementException问题定位

    Iterator 迭代器越界 例子如下: Iterator i = set.iterator(); while (i.hasNext()) { System.out.println(i.next()) ...

  8. B. Obtaining the String(模拟)

    比较水的模拟 思路:就是模拟题意 注意:把数组开大点,开始wa了几次就是这个原因 #include<iostream> #include<string> #include< ...

  9. 如何在已有的 Web 应用中使用 ReactJS

    原文:How to Sprinkle ReactJS into an Existing Web Application 译者:nzbin 当我们学习一项新技术,可能是一个 JavaScript 框架, ...

  10. 利用CocoaHttpServer搭建手机本地服务器

    原理 使用CocoaHTTPServer框架,在iOS端建立一个本地服务器,只要电脑和手机连入同一热点或者说网络,就可以实现通过电脑浏览器访问iOS服务器的页面,利用POST实现文件的上传. 实现 1 ...