您的位置:首页 > 博客中心 > 网络系统 >

Linux环境编程之文件I/O(五):fcntl函数

时间:2022-04-03 09:05

引言:

对于一个普通的文件,我们可以想到的对它的操作有,读取文件的内容、写数据到文件中,这些都是前面提到的read、write函数的作用。除此之外,还可以获取文件的其他性质,并对这些性质进行修改,比如文件的描述符、文件描述符标记、文件状态标志等等。这些对文件性质的修改就由fcntl函数完成。


函数介绍:

       #include <unistd.h>
       #include <fcntl.h>
       int fcntl(int fd, int cmd, ... /* arg */ );

参数:

fd:欲设置的文件描述符。

cmd:打算对文件进行操作的指令。

arg:一般情况下,该参数为一个整数,当使用记录锁时,它指向一个结构的指针。

功能:根据cmd的不同,fcntl函数有以下5种功能:

1、复制一个现有的描述符(cmd = F_DUPFD)。

2、获得/设置文件描述符标记(cmd = F_GETFD或F_SETFD)。

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

4、获得/设置异步I/O所有权(cmd = F_GETOWN或F_SETOWN)。

5、获得/设置记录锁(cmd = F_GETLK、F_SETLK或F_SETLKW)。


详细说明:

1、F_DUPFD 

复制文件描述符fd。新文件描述符作为函数值返回。它是尚未打开的个描述符中大于或等于第三个参数(取为整数值)中各值的最小值。新描述符与fd共享同一文件表项。但是新描述符有它自己的一套文件描述符标志,其FD_CLOEXEC文件描述符标志被清除。其实,此时fcntl函数的功能与dup2的功能类似。

/*
 * File Name : fupfd.c
 * Author    : libing
 * Mail      : libing1209@126.com
 * Function  : just for a test
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int
main(void)
{
	int fd, newfd;
	fd = open("test.txt", O_RDWR);
	if(fd == -1){
		printf("can‘t open test.txt.\n");	
		exit(1);
	}
        //使用fcntl函数复制文件描述符
	newfd = fcntl(fd, F_DUPFD, 5);
	printf("newfd = %d.\n", newfd);

	return 0;
}
编译测试:

编译程序:
gcc fupfd.c
执行程序:
./a.out
测试结果:
newfd = 5.
2、F_GETFD:对应于fd的文件描述符标志作为函数返回。当前仅定义了一个文件描述符标志FD_CLOEXEC。

      F_SETFD:对于fd设置文件描述符标志。新标志按第三个参数设置。

3、F_GETFL:对于fd的文件状态标志作为函数值返回。文件状态标志有O_RDONLY、O_WRONLY、O_RDWR等。因为三个访问方式标志并不各占1位。因此首先必须用屏蔽字O_ACCMODE取得访问模式位,然后将结果与这三种值的任一种做比较。

      F_SETFL:将文件状态标志设置为第三个参数的值。可以更改的几个标志是:O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC等。

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
	int val;
	int fd;

	fd = open("test.txt", O_RDWR);
        //fcntl函数获得文件状态标志
	if((val = fcntl(fd, F_GETFL, 0)) < 0)
			printf("fcntl failed.\n");

	switch(val & O_ACCMODE){
	case O_RDONLY:
		printf("read only");	
		break;
	case O_WRONLY:
		printf("write only");	
		break;
	case O_RDWR:
		printf("read and write");	
		break;
	default:
		printf("unknown access mode");
	}

	if(val & O_APPEND)
			printf("append");
	if(val & O_NONBLOCK)
			printf("nonblock");


	putchar(‘\n‘);
	exit(0);
}
编译测试结果:

编译程序:
gcc fcntl.c
执行程序:
./a.out
结果显示:
read and write
4、F_GETOWN:取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。

      F_GETOWN:设置接收SIGIO和SIGURG信号的进程ID或进程组ID。






Linux环境编程之文件I/O(五):fcntl函数,布布扣,bubuko.com

本类排行

今日推荐

热门手游