系统编程-文件IO-fcntl系统调用

 

原型:

#include <unistd.h>
#include <fcntl.h>

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

功能: 改变已经打开文件的性质

 

常见使用方式:

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

int fcntl(int fd, int cmd, struct flock*lock);

*复制一个已有的文件描述符,新文件描述符作为函数返回值(cmd=F_DUPFD)

*获得/设置文件描述符标志(cmd=F_GETFD或F_SETFD)

*获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)

       通过第三个参数来设置

  可以更改的几个标志是O_APPEND、O_NONBLOCK、SYNC、O_ASYNC,

  而O_RDONLY、O_WRONLY、O_RDWR不适用(只读状态标志、只写状态标志、读写状态标志,不可以更改,这些只能是在文件进行open的时候设置的哦!)

*获得/设置文件锁(cmd=F_SETLK、cmd=F_GETLK、F_SETLKW)

 

 

文件状态标志设置案例,实验

实验思路:使用int open(const char *pathname, int flags);

                  打开文件描述符的时候,flag先设置为O_WRONLY, 再使用set_fl追加O_APPEND文件状态标志,然后写入文件内容观察效果,作为实验1。

                  在实验1的set_fl后方再次调用clr_fl(fd, O_APPEND)清除O_APPEND文件状态标志,然后写入文件内容观察效果,作为实验2。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

void set_fl(int fd, int flag){

    int val = fcntl(fd, F_GETFL);
    val |= flag;

   if( fcntl(fd, F_SETFL, val) <0 ){
      fprintf(stderr, "fcntl error:%s \n ", strerror(errno));
   }
}

void clr_fl(int fd, int flag){

    int val = fcntl(fd, F_GETFL);
    val &= ~flag;

  if( fcntl(fd, F_SETFL, val) <0 ){
    perror("fcntl error: ");
  }
}


int main()
{
  printf(".. \n");
  int fd = open("tmp.txt", O_WRONLY | O_CREAT);
  
  unsigned char buff1[] = "hello-";
  unsigned char buff2[] = "jack\n";

  ssize_t writebytes = -1;
  writebytes = write(fd, buff1, sizeof(buff1));
  printf("writebytes:[%ld] bytes .. \n", writebytes);

  set_fl(fd, O_APPEND);

  writebytes = write(fd, buff2, sizeof(buff2));
  printf("writebytes:[%ld] bytes .. \n", writebytes);

  return 0;
}

实验结果:

解析:

第1次./ab执行,cat显示“hello-jack”,这个应该没有疑惑。

第2次./ab执行,之前的tmp.txt内已经存在文本“hello-jack”。

第2次./ab内的第一次write,文件读写指针是从头开始的,所以覆写了前面的“hello-” 。(注意,这里所谓覆写,即覆盖写入了一次,所以肉眼观察不到)

第二次write之前,使用set_fl追加了O_APPEND文件标志,所以文件读写指针偏移到了文件末尾,在文件末尾进行了一次write,使得文件末尾多出了“jack”文本内容。

 

第3次./ab执行,原理同上。

 

 将上述实验代码内的set_fl(fd, O_APPEND) 修改为 clr_fl(fd, O_APPEND), 则每次执行,tmp.txt内的内容都是“hello-jack”。

 

 

 

 

 

.

posted @ 2020-10-10 05:52  一匹夫  阅读(150)  评论(0编辑  收藏  举报