UNIX环境编程学习笔记(5)——文件I/O之fcntl函数访问已打开文件的性质

lienhua34
2014-08-29

fcntl 函数可以改变已打开的文件的性质。

#include <fcntl.h>

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

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)。

下面说明一下前五个 cmd 值。

(1)F_DUPFD

复制文件描述符 filedes。新文件描述符作为函数值返回。跟 dup 函数的区别是:dup 函数返回的新文件描述符一定是尚未打开的描述符中最小的,而 fcntl 函数返回的新文件描述符是尚未打开的描述符中大于或等于第三个参数中各值的最小值。即 dup(filedes) 等价于 fcntl(filedes, F_DUPFD, 0)

(2)F_GETFD

获取 filedes 的文件描述符标志作为函数值返回。当前只定义了一个文件描述符标志FD_CLOEXEC(FD_CLOEXEC 即“执行时关闭”标志,设置了该标志,表示在执行一个 exec 时自动关闭该描述符。复制一个文件描述符时自动清除该标志,无论使用的是 dup 函数还是 fcntl 函数。)

(3)F_SETFD

设置 filedes 文件描述符标志。

(4)F_GETFL

获取文件描述符 filedes 的文件状态标志作为函数值返回。文件状态标志见表格 1,

文件状态标志  说明
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 为读、写打开
O_APPEND 每次写时追加
O_NONBLOCK 非阻塞模式
O_SYNC 等待写完成(数据和属性)
O_DSYNC 等待写完成(仅数据)
O_RSYNC 同步读、写

三个访问方式标志(O_RDONLY、O_WRONLY 以及O_RDWR)并不各占一位,这三个标志的值分别为 0、1 和 2。因此需要必须使用屏蔽字O_ACCMODE 获取访问模式位,然后将结果与这三种值中任一种做比较。

(5)F_SETFL

将文件状态标志设置为第三个参数的值(取为整 型 值) 可 以 更 改 的 几 个 标 志 是:O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC 和O_RSYNC。

例子:

下面程序的第一个参数指定文件描述符,并对于该描述符打印其所选择的文件状态标志说明。

#include <stdlih.h>
#include <stdio.h>
#include <fcntl.h>
int
main(int argc, char *argv[])
{
    int val;
    if (argc != 2) {
        printf("usage: a.out <descriptor#>");
        exit(-1);
    }
    if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0) {
        printf("fcntl error for fd %d", atoi(argv[1]));
        exit(-1);
    }
    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:
        err_dump("unknown access mode");
        break;
    }
    if (val & O_APPEND) {
        printf(", append");
    }
    putchar(‘\n‘);
    exit(0);
}

编译该程序,生成 flprinter,然后运行该文件,

lienhua34:examples$ ./flprinter 0 < /dev/tty
read only
lienhua34:examples$ ./flprinter 1 > temp.foo
lienhua34:examples$ cat temp.foo
write only
lienhua34:examples$ ./flprinter 2 2>>temp.foo
write only, append
lienhua34:examples$ ./flprinter 5 5<>temp.foo
read write

(done)

时间: 2024-10-14 12:36:21

UNIX环境编程学习笔记(5)——文件I/O之fcntl函数访问已打开文件的性质的相关文章

UNIX环境编程学习笔记(20)——进程管理之exec 函数族

lienhua342014-10-07 在文档“进程控制三部曲”中,我们提到 fork 函数创建子进程之后,通常都会调用 exec 函数来执行一个新程序.调用 exec 函数之后,该进程就将执行的程序替换为新的程序,而新的程序则从 main 函数开始执行. UNIX 提供了 6 种不同的 exec 函数供我们使用.它们的原型如下所示, #include <unistd.h>int execl(const char *pathname, const char *arg0, ... /* (cha

UNIX环境编程学习笔记(6)——文件I/O之判断文件类型

lienhua342014-09-01 1 文件类型 我们平时最常接触的文件类型有普通文件(regular file)和目录(di-rectory file),但是 UNIX 系统提供了多种文件类型: (1) 普通文件(regular file) 这种文件包含了某种形式的数据,这些数据无论是文件还是二进制对于 UNIX 内核而言都是一样的.对普通文件内容的解释有处理该文件的应用程序进行. (2) 目录文件(directory file) 目录文件包含了其他文件的名字以及指向与这些文件有关信息的指

UNIX环境编程学习笔记(10)——文件I/O之硬链接和符号链接

lienhua342014-09-15 1 文件系统数据结构 UNIX 文件系统通过 i 节点来存储文件的信息.如图 1 所示为一个磁盘柱面上的 i 节点和数据块示意图.其中 i 节点是一个固定长度的记录项,它包含了有关文件的大部分信息.数据块用于存储文件的实际内容.每个文件的 i 节点会记录该文件的内容所占用的数据块信息. 图 1: i 节点和数据块 图 1 中还有一些信息需要进行说明: 1. 每个目录项只存储了文件的文件名和 i 节点编号(每个文件系统各自对它们的 i 节点进行编号).文件的

UNIX环境编程学习笔记(8)——文件I/O之校验当前登录用户对文件的访问权限

lienhua342014-09-03 通过前面一篇随笔(文件访问权限与进程访问控制),我们知道内核校验文件的访问权限使用的是进程的有效用户 ID 和有效组 ID.但有时我们需要知道当前登录用户对某个文件访问权限.虽然说进程的有效用户 ID 和有效组 ID 通常分别等于当前登录用户 ID 和用户所在组 ID.例如,一个进程可能因设置用户 ID 以另一个用户权限运行,它仍可能想验证当前实际登录的用户是否能否访问一个给定的文件. access 函数提供了按照实际用户 ID 和实际组 ID 进行访问权

UNIX环境编程学习笔记(13)——文件I/O之标准I/O流

lienhua342014-09-29 1 标准 I/O 流 之前学习的都是不带缓冲的 I/O 操作函数,直接针对文件描述符的,每调用一次函数可能都会触发一次系统调用,单次调用可能比较快捷.但是,对于需要频繁进行 I/O 操作的程序,频繁触发系统调用产生的消耗太大. 标准 I/O 库提供了带缓冲的 I/O 操作函数,这些函数围绕着一种叫做流(stream)的东西进行.当使用标准 I/O 库打开或创建一个文件时,系统提供了一个流与这个文件相关联.通过流的读入和输出完成所需要的 I/O操作. 标准

UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符

lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int filedes); int dup2(int filedes, int filedes2); 返回值:若成功则返回新的文件描述符,如出错则返回-1. 由 dup 函数返回的文件描述符一定是当前可用文件描述符中的最小描述符.用 dup2 函数则可以通过参数 filedes2 指定目标文件描述符.如果filedes2

UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改

lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位  st_mode 屏蔽  意义  S_IRUSR  用户 -读  S_IWUSR  用户 -写  S_IXUSR  用户 -执行  S_IRGRP   组 -读  S_IWGRP  组 -写  S_IXGRP  组 -执行  S_IROTH  其他 -读  S_IWOTH  其他 -写  S_IXOTH  其他

UNIX环境编程学习笔记(7)——文件I/O之文件访问权限与进程访问控制

lienhua342014-09-02 1 文件的设置用户 ID位 和设置组 ID位 与进程相关联的 ID 如下表所示, 表 1: 与进程相关联的用户 ID 和组 ID 实际用户 ID 我们实际上是谁 实际组 ID 有效用户 ID 用于文件访问权限检查 有效组 ID 附加组 ID 保存的设置用户 ID 由 exec 函数保存 保存的设置组 ID 保存的设置用户 ID 和保存的设置组 ID 在执行一个程序时包含了有效用户 ID 和有效组 ID 的副本,这个后面我们学习到进程时在详细学习. 此处,我

UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构

lienhua342014-08-27 内核使用三种数据结构表示打开的文件,分别是文件描述符表.文件表和 V 节点表. (1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每个描述符占用一项.与每个文件描述符相关联的是: (a) 文件描述符标志. (b) 指向一个文件表项的指针. (2) 内核为所有打开文件维持一张文件表.每个文件表项包含: (a) 文件状态标志(读.写.添写.同步和非阻塞等). (b) 当前文件偏移量. (c) 指向该文件 V 节点表项的指针. (3)