linux c編程之fcntl


 

  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時,不等待用戶輸入而直接返回錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM