`

fcntl 函数介绍

阅读更多
    fcntl 函数可以改变已经打开的文件的属性。
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* int arg */);
                    /* 返回值:若成功,则依赖于 cmd;否则,返回 -1 */

    在本节的各实例中,第三个参数总是一个整数,但在后面说明记录锁时,它则是一个指向一个结构的指针。
    fcntl 函数有以下 5 种功能:
    (1) 复制一个已有的描述符(cmd = F_DUPFD / F_DUPFD_CLOEXEC)。
    (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)。
    在此先说明11种 cmd 中的前8种,后3种待后边介绍记录锁时再进行介绍。我们将讨论与进程表项中各文件描述符相关联的文件描述符标志以及每个文件表项中的文件状态标志。
    F_DUPFD:复制文件描述符 fd。新文件描述符作为函数值返回,它是尚未打开的各描述符中大于或等于第三个参数值(取为整型值)中各值的最小值,它与 fd 共享同一文件表项。但是,它有它自己的一套文件描述符标志,其 FD_CLOEXEC 文件描述符标志被清除(这表示该描述符在 exec 时仍保持有效。很多现有的与文件描述符标志有关的程序并不使用常量 FD_CLOEXEC,而是将此标志设置为 0 (系统默认,在 exec 时不关闭)或 1 (在 exec 时关闭))。
    F_DUPFD_CLOEXEC:复制文件描述符,设置与新描述符关联的 FD_CLOEXEC 文件描述符标志的值,返回新文件描述符。
    F_GETFD:对应于 fd 的文件描述符标志作为函数值返回。当前只定义了一个文件描述符标志 FD_CLOEXEC。
    F_SETFD:对应于 fd 设置文件描述符标志。新标志值按第3个参数(取为整数值)设置。
    F_GETFL:对应于 fd 的文件状态标志作为函数值返回。遗憾的是,open 函数中的 5 个文件状态标志(O_RDONLY、O_WRONLY、O_RDWR、O_EXEC 以及 O_SEARCH)并不各占 1 位,而且这 5 个值互斥,一个文件的访问方式只能取其中之一。因此首先必须用屏蔽字 O_ACCMODE 取得访问方式位,然后将结果与这 5 个值中的每一个相比较。
    F_SETFL:将文件状态标志设置为第 3 个参数的值(取为整数值)。可以更改的几个标志是:O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC 和 O_ASYNC。
    F_GETOWN:获取当前接收 SIGIO 和 SIGURG 信号的进程 ID 或进程组 ID。
    F_SETOWN:设置接收 SIGIO 和 SIGURG 信号的进程 ID 或进程组 ID。正的 arg 指定一个进程 ID,负的 arg 表示等于 arg 绝对值的一个进程组 ID。
    下面这个示例可用来打印指定文件描述符所选择的文件状态标志。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char *argv[]){
	int val;

	if(argc != 2){
		printf("usage: %s <descriptor>\n", argv[0]);	
		exit(1);
	}

	if((val=fcntl(atoi(argv[1]), F_GETFL, 0)) < 0){
		printf("fcntl() error for fd %s\n", argv[1]);
		exit(2);
	}

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

	if(val & O_APPEND)
		printf(", append");
	if(val & O_NONBLOCK)
		printf(", nonblocking");
	if(val & O_SYNC)
		printf(", synchronous writes");

#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
	if(val & O_FSYNC)
		printf(", synchronous writes");
#endif
	
	putchar('\n');
	exit(0);
}

    下面是从 bash 中执行的结果(使用其它 shell 可能结果会有所不同):
$./a.out 0 < /dev/tty
read only
$./a.out 1 > temp.foo
$cat temp.foo
write only
$./a.out 2 2>>temp.foo
write only, append
$./a.out 5 5<>temp.foo     # 表示在文件描述符 5 上打开文件 temp.foo 以供读、写
read write

    在修改文件描述符标志或文件状态标志时必须谨慎,要先获得现在的标志值,然后按照期望修改它,最后设置新标志值,不能只是执行 F_SETFD 或 F_SETFL 命令,这样会关闭以前设置的标志位。下面是对一个文件描述符设置一个或多个文件状态标志的函数示例:
#include <stdlib.h>
#include <fcntl.h>

void set_fl(int fd, int flags){	// flags are file status flags to turn on.
	int val;
	if((val=fcntl(fd, F_GETFL, 0)) < 0){
		printf("fcntl F_GETFL error\n");
		exit(2);
	}

	val |= flags;	// turn on flags
	
	if(fcntl(fd, F_SETFL, val) < 0){
		printf("fcntl F_SETFL error\n");
		exit(2);
	}
}

void clr_fl(int fd, int flags){	// flags are file status flags to turn off.
	int val;
	if((val=fcntl(fd, F_GETFL, 0)) < 0){
		printf("fcntl F_GETFL error\n");
		exit(2);
	}

	val &= ~flags;	// turn flags off
	
	if(fcntl(fd, F_SETFL, val) < 0){
		printf("fcntl F_SETFL error\n");
		exit(2);
	}
}

分享到:
评论

相关推荐

    fcntl函数的功能介绍

    ### fcntl函数的功能介绍 `fcntl`函数是一个用于操作系统中文件描述符管理和文件状态更改的重要接口。通过调用`fcntl`函数,用户可以实现多种不同的功能,如复制文件描述符、获取或设置文件描述符标志等。下面将...

    fcntl函数复制文件描述符

    fcntl函数复制文件描述符,此例只是用来留作笔记,

    fcntl函数的使用详解

    fcntl函数在Linux操作系统中是一个非常重要的文件控制函数,它提供了对文件的各种高级操作,包括文件锁的设置。在多用户共享文件的场景中,fcntl函数能够帮助防止数据冲突,通过实施强制性锁或建议性锁确保文件访问...

    fcntl使用.doc

    fcntl 函数使用详解 fcntl 函数是 Unix 操作系统中一个非常强大的函数,它提供了对文件描述符的控制和管理功能。该函数的使用可以分为五个方面:复制文件描述符、获取和设置文件描述符标记、获取和设置文件状态标记...

    linux fcntl()函数

    ### Linux fcntl() 函数详解 #### 概述 `fcntl()` 函数是 Linux 下用于对文件描述符执行各种操作的系统调用。通过该函数,可以实现对文件描述符的复制、获取或设置文件描述符标志、锁定文件等操作。 #### 函数...

    fcntl.py文件下载

    `fcntl.py` 文件是Python标准库中的一个模块,主要用于提供与Unix系统中`fcntl`函数相关的功能。在Linux操作系统中,`fcntl`是一组用于控制和同步文件的系统调用,它源自C语言中的`fcntl.h`头文件。在Windows系统上...

    Linux编程下的fcntl文件锁代码

    在Linux系统中,fcntl函数是用于执行各种文件控制操作的关键函数。这个函数广泛应用于实现文件锁,以确保多个进程在访问同一文件时的同步和互斥。本篇将深入探讨fcntl文件锁的概念、使用方法以及如何通过提供的源...

    fcntl.py文件

    这个模块的命名直接来源于C语言中对应的头文件`fcntl.h`,在C编程中,`fcntl`函数集用于实现诸如文件锁、文件描述符选项设置以及文件状态查询等高级文件操作。 fcntl模块的核心功能包括: 1. **文件锁定**:在多...

    解决这个错误问题:importerror no module named fcntl

    它主要在Unix和类Unix系统(如Linux、macOS)上使用,因为在Windows系统中并不存在`fcntl`函数库。 当你尝试运行包含`import fcntl`语句的代码时,如果系统中未安装`fcntl`模块或`PYTHONPATH`环境变量未包含`fcntl`...

    《嵌入式操作系统》实验教学大纲:实验四-Linux进程及文件操作程序设计.doc

    fcntl 函数是 Linux 中最常用的文件锁函数,它可以用于建立记录锁和文件锁。fcntl 函数的格式如下所示: int fcntl(int fd, int cmd, struct flock *lock) 其中,fd 是文件描述符,cmd 是命令,lock 是锁参数。cmd...

    linux内核异步通知用户空间fasync

    1. `fasync_helper`函数:这个函数用于注册一个文件描述符到`fasync`队列,使得当相关设备有数据可用时,可以异步地唤醒用户空间的进程。它通常在文件操作结构的`fasync`方法中调用,接受三个参数——文件描述符、...

    fcntl的调用

    `fcntl`函数是Unix-like操作系统中的一个非常重要的系统调用,它允许程序员对文件描述符进行多种控制操作,包括设置和获取文件的状态标志、管理文件锁、处理信号以及监控文件和目录的变化。以下是对`fcntl`函数各...

    Python使用文件锁实现进程间同步功能【基于fcntl模块】

    Linux系统提供了文件整体上锁(flock)和更细粒度的记录上锁(fcntl)功能,底层功能均可由fcntl函数实现。 首先来了解记录上锁。记录上锁是读写锁的一种扩展类型,它可用于有亲缘关系或无亲缘关系的进程间共享某个文件...

    详细介绍dup2函数用法,一看必懂.。。。

    `dup` 和 `dup2` 函数可以通过 `fcntl` 函数实现相同的功能。例如,`dup(oldfd)` 等价于: ```c fcntl(oldfd, F_DUPFD, 0); ``` 而 `dup2(oldfd, newfd)` 等价于: ```c close(newfd); fcntl(oldfd, F_DUPFD, ...

    一个简单聊天室的两种实现 (fcntl 和 select)

    通过以上介绍,我们可以看出,无论是使用`fcntl`还是`select`来实现多路I/O通信,都能够有效地管理聊天室中的多个连接,提高程序的响应能力和处理能力。具体选择哪种方法取决于实际应用场景的需求和个人喜好。通常...

    C语言标准函数库速查手册.chm

    9. **文件操作**:&lt;fcntl.h&gt;和头文件中的函数,如open()打开文件,read()和write()读写文件,close()关闭文件,fstat()获取文件状态。 10. **目录操作**:头文件中的函数,如opendir()打开目录,readdir()读取目录...

    linux网络编程-客户端与服务器端异步通信,fcntl,accept

    本主题将深入探讨客户端与服务器之间的异步通信,以及如何利用`fcntl`和`accept`这两个重要的函数来实现这一目标。 首先,我们来看客户端与服务器端的异步通信。在传统的同步通信模式中,客户端发送请求后会等待...

Global site tag (gtag.js) - Google Analytics