菜鸟笔记
提升您的技术认知

linux c编程之fcntl-ag真人游戏

 

  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 
#include 
#include 
#include 
#include 
#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 
#include 
#include 
#include 
#include 
#include 
#include 
#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时,不等待用户输入而直接返回错误。

网站地图