- 浏览: 142427 次
文章分类
最新评论
fcntl 函数可以改变已经打开的文件的属性。
在本节的各实例中,第三个参数总是一个整数,但在后面说明记录锁时,它则是一个指向一个结构的指针。
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。
下面这个示例可用来打印指定文件描述符所选择的文件状态标志。
下面是从 bash 中执行的结果(使用其它 shell 可能结果会有所不同):
在修改文件描述符标志或文件状态标志时必须谨慎,要先获得现在的标志值,然后按照期望修改它,最后设置新标志值,不能只是执行 F_SETFD 或 F_SETFL 命令,这样会关闭以前设置的标志位。下面是对一个文件描述符设置一个或多个文件状态标志的函数示例:
#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); } }
发表评论
-
打开伪终端设备
2018-07-09 20:50 1252在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1550伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 800多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 950终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 569尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 944虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 710tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 815终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 439终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 579在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 947在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 617在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 497消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 485有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 421FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 389管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 889readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 455POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 615记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 439UNIX 系统中,守护进程遵循下列通用惯例。 ...
相关推荐
### fcntl函数的功能介绍 `fcntl`函数是一个用于操作系统中文件描述符管理和文件状态更改的重要接口。通过调用`fcntl`函数,用户可以实现多种不同的功能,如复制文件描述符、获取或设置文件描述符标志等。下面将...
fcntl函数复制文件描述符,此例只是用来留作笔记,
fcntl函数在Linux操作系统中是一个非常重要的文件控制函数,它提供了对文件的各种高级操作,包括文件锁的设置。在多用户共享文件的场景中,fcntl函数能够帮助防止数据冲突,通过实施强制性锁或建议性锁确保文件访问...
fcntl 函数使用详解 fcntl 函数是 Unix 操作系统中一个非常强大的函数,它提供了对文件描述符的控制和管理功能。该函数的使用可以分为五个方面:复制文件描述符、获取和设置文件描述符标记、获取和设置文件状态标记...
### Linux fcntl() 函数详解 #### 概述 `fcntl()` 函数是 Linux 下用于对文件描述符执行各种操作的系统调用。通过该函数,可以实现对文件描述符的复制、获取或设置文件描述符标志、锁定文件等操作。 #### 函数...
`fcntl.py` 文件是Python标准库中的一个模块,主要用于提供与Unix系统中`fcntl`函数相关的功能。在Linux操作系统中,`fcntl`是一组用于控制和同步文件的系统调用,它源自C语言中的`fcntl.h`头文件。在Windows系统上...
在Linux系统中,fcntl函数是用于执行各种文件控制操作的关键函数。这个函数广泛应用于实现文件锁,以确保多个进程在访问同一文件时的同步和互斥。本篇将深入探讨fcntl文件锁的概念、使用方法以及如何通过提供的源...
这个模块的命名直接来源于C语言中对应的头文件`fcntl.h`,在C编程中,`fcntl`函数集用于实现诸如文件锁、文件描述符选项设置以及文件状态查询等高级文件操作。 fcntl模块的核心功能包括: 1. **文件锁定**:在多...
它主要在Unix和类Unix系统(如Linux、macOS)上使用,因为在Windows系统中并不存在`fcntl`函数库。 当你尝试运行包含`import fcntl`语句的代码时,如果系统中未安装`fcntl`模块或`PYTHONPATH`环境变量未包含`fcntl`...
fcntl 函数是 Linux 中最常用的文件锁函数,它可以用于建立记录锁和文件锁。fcntl 函数的格式如下所示: int fcntl(int fd, int cmd, struct flock *lock) 其中,fd 是文件描述符,cmd 是命令,lock 是锁参数。cmd...
`fcntl`函数是Unix-like操作系统中的一个非常重要的系统调用,它允许程序员对文件描述符进行多种控制操作,包括设置和获取文件的状态标志、管理文件锁、处理信号以及监控文件和目录的变化。以下是对`fcntl`函数各...
1. `fasync_helper`函数:这个函数用于注册一个文件描述符到`fasync`队列,使得当相关设备有数据可用时,可以异步地唤醒用户空间的进程。它通常在文件操作结构的`fasync`方法中调用,接受三个参数——文件描述符、...
Linux系统提供了文件整体上锁(flock)和更细粒度的记录上锁(fcntl)功能,底层功能均可由fcntl函数实现。 首先来了解记录上锁。记录上锁是读写锁的一种扩展类型,它可用于有亲缘关系或无亲缘关系的进程间共享某个文件...
`dup` 和 `dup2` 函数可以通过 `fcntl` 函数实现相同的功能。例如,`dup(oldfd)` 等价于: ```c fcntl(oldfd, F_DUPFD, 0); ``` 而 `dup2(oldfd, newfd)` 等价于: ```c close(newfd); fcntl(oldfd, F_DUPFD, ...
通过以上介绍,我们可以看出,无论是使用`fcntl`还是`select`来实现多路I/O通信,都能够有效地管理聊天室中的多个连接,提高程序的响应能力和处理能力。具体选择哪种方法取决于实际应用场景的需求和个人喜好。通常...
9. **文件操作**:<fcntl.h>和头文件中的函数,如open()打开文件,read()和write()读写文件,close()关闭文件,fstat()获取文件状态。 10. **目录操作**:头文件中的函数,如opendir()打开目录,readdir()读取目录...
本主题将深入探讨客户端与服务器之间的异步通信,以及如何利用`fcntl`和`accept`这两个重要的函数来实现这一目标。 首先,我们来看客户端与服务器端的异步通信。在传统的同步通信模式中,客户端发送请求后会等待...