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. SQL 日期时间比较

    原先的判断是 ae.首次受理时刻 >= '2015/12/1 0:00:00'  AND ae.首次受理时刻 <= '2015/12/25 0:00:00' ,改为如下和时间变量比较 效率 ...

  2. springboot运行时该注意的地方

    1.SpringBoot的入口类一定要放在所有类的上一层,也就是要包含所有子包中的类 springBoot在启动时才会加载所有子包中的所有组件 否则会出现启动成功但是访问不到的情况: This app ...

  3. android SDK 无法更新

    android-windows-sdk无法更新解决办法:   1.在host文件新增如下配置 (host文件位置:c:\Windows\System32\drivers\etc文件夹下面,用文本编辑器 ...

  4. java反射(java.lang.reflect) ---普通单例模式唯一性问题

    1. 普通的饱汉式.饿汉式 package org.bighead.test2; public class TestPrivate { private String str = "strPr ...

  5. SM4加密算法实现Java和C#相互加密解密

    SM4加密算法实现Java和C#相互加密解密 近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多 ...

  6. SpringCloud 学习网址记录

    SpringCloud Gateway https://www.cnblogs.com/ityouknow/p/10141740.html 熔断降级的概念 https://blog.csdn.net/ ...

  7. 用CMD打开chrome并导航到百度(golang)

    首选在cmd中输入(注意:根据你的电脑路径修改,可能是Progra~1): C:\Progra~\Google\Chrome\Application\chrome.exe www.baidu.com ...

  8. Java base64转图片

    import sun.misc.BASE64Decoder; import java.io.FileOutputStream; import java.io.OutputStream; public ...

  9. Openwrt无线中继设置并访问外网

    Openwrt无线中继设置并访问外网 本篇博文参考来自:http://blog.csdn.net/pifangsione/article/details/13162023 配置目标 主路由器使用AP模 ...

  10. Java项目的导入和导出

    在很多情况下,需要将当前的 Java工程传递给其他人继续工作, 或协同工作,或者是从其他人那里接收到传递来的Java项目, 就需要掌握 Java项目的导入和导出. 以 Hello World 为例: ...