open , openat , openx , openxat , open64, open64at, open64x, open64xat, creat 或 creat64 子例程

用途

打开文件以进行读取或写入。

语法

#include <fcntl.h>
int open (Path, OFlag [, Mode])
const char *Path;
int OFlag;
mode_t Mode;
int openat (DirFileDescriptor, Path, OFlag [, Mode])
int DirFileDescriptor;
const char *Path;
int OFlag;
mode_t Mode;
int openx (Path, OFlag, Mode, Extension)
const char *Path;
int OFlag;
mode_t Mode;
long Extension;
int openxat (DirFileDescriptor, Path, OFlag, Mode, Extension)
int DirFileDescriptor;
const char * Path;
int OFlag;
mode_t Mode;
long Extension;
int creat (Path, Mode)
const char *Path;
mode_t Mode;
int open64 (Path, OFlag [, Mode])
const char *Path;
int OFlag;
mode_t Mode;
int open64at (DirFileDescriptor, Path, 
OFlag [, Mode])
int DirFileDescriptor;
const char * Path;
int OFlag;
mode_t Mode;
int creat64 (Path, Mode)
const char *Path;
mode_t Mode;
int open64x (Path, OFlag, Mode, Extension)
char *Path;
int64_t OFlag;
mode_t Mode;
ext_t Extension;
int open64xat (DirFileDescriptor, Path, OFlag, Mode, Extension)
int DirFileDescriptor;
char *Path;
int64_t OFlag;
mode_t Mode;
ext_t Extension;

描述

如果DirFileDescriptor参数为AT_FDCWD,或者Path参数为绝对路径名,则 "openat子程序等同于 "open子程序。 如果DirFileDescriptor是打开目录的有效文件描述符,且Path是相对路径名,则Path将被视为相对于与DirFileDescriptor参数关联的目录,而不是当前工作目录。 同样, openxatopen64atopen64xat 子例程分别与 openxopen64open64x 子例程等效,其方式与 openatopen相同。

openopenxcreat 子例程在 Path 参数指定的文件与文件描述符之间建立连接。 打开的文件描述符由后续 I/O 子例程 (例如 readwrite) 用于访问该文件。

openx 子例程与 open 子例程相同,添加了供设备驱动程序使用的 Extension 参数。 creat 子例程等同于设置了 O_WRONLYO_CREATO_TRUNC 标志的 open 子例程。

返回的文件描述符是先前未对该进程打开的最低文件描述符。 任何进程都不能同时打开超过 OPEN_MAX 个文件描述符。

文件偏移量 (标记文件中的当前位置) 被设置为文件的开头。 新的文件描述符设置为在 exec 子例程之间保持打开状态。

open64creat64 子例程等同于 opencreat 子例程,只是在与返回的文件描述符相关联的打开文件描述中设置了 O_LARGEFILE 标志。 此标志允许访问大于 OFF_MAX 的文件。 如果调用者尝试打开大于 OFF_MAX 且未设置 O_LARGEFILE 的文件,那么打开将失败,并且 errno 将设置为 EOVERFLOW

在启用了大文件的编程环境中, open 将重新定义为 open64creat 将重新定义为 creat64

open64x 子例程在加密文件系统 (EFS) 中创建和访问加密文件。 open64x 子例程类似于 openx 子例程,通过修改 OFlag 参数,将其更新为 64 位数量。

如果 "openat、"openxat、"open64at"或 "open64xat"子程序中的DirFileDescriptor参数在打开时未使用O_SEARCH打开标志,则该子程序会通过使用目录的当前权限来检查是否允许对该目录进行目录搜索。 如果该目录是使用 O_SEARCH 打开标志打开的,那么子例程不会对该目录执行检查。

参数

表 1. 参数
描述
DirFileDescriptor 指定打开的目录的文件描述符。
路径 指定要打开的文件。 如果指定了DirFileDescriptor,且 Path 是相对路径名,则Path将被视为相对于DirFileDescriptor 指定的目录。
方式 指定要创建的文件的读许可权,写许可权和执行许可权 (由 创建 0 个 标志请求)。 如果该文件已存在,那么将忽略此参数。 Mode 参数通过对 <sys/mode.h> 文件中定义的以下一个或多个值进行逻辑 OR 运算来构造:
ISUID
启用可执行文件的 setuid 属性。 执行此程序的进程将获取文件所有者的访问权。
_ISGID
启用可执行文件的 setgid 属性。 执行此程序的进程获取该文件的组的访问权。 此外,还会对目录启用组继承属性。 在此目录中创建的文件具有等于该目录的组的组。

下列属性仅适用于直接可执行的文件。 当应用于可执行文本文件 (例如 shell 脚本和 awk 脚本) 时,它们没有意义。

ISVTX
启用目录的 link/unlink 属性。 无法在此目录中链接到文件。 仅当请求进程对该目录具有写许可权并且是该文件或该目录的所有者时,才可以取消链接文件。
ISVTX
启用可执行文件的 save text 属性。 该程序在使用后未取消映射。
(_ENFMT)
对常规文件启用强制执行方式记录锁定。 使用 lockf 子例程请求的文件锁定被强制实施。
_IRUSR
允许文件的所有者读取该文件。
(_IWUSR)
允许文件所有者对其进行写操作。
(_IXUSR)
允许该文件的所有者执行该文件 (或搜索目录)。
_ IRGRP
允许该文件的组读取该文件。
(_I)
允许该文件的组写入该文件。
_IXGRP
允许该文件的组执行该文件 (或搜索目录)。
_IROTH
允许其他人读取该文件。
工单工单
允许其他用户写入该文件。
_IXOTH
允许其他用户执行该文件 (或搜索目录)。

存在可以使用 mknod 子例程设置但不能使用 chmod 子例程设置的其他方式值。

扩展名 提供与需要其他信息或返回其他状态的字符设备驱动程序的通信。 每个驱动程序都以与设备相关的方式将 扩展 参数解释为值或指向通信区域的指针。 当 扩展 参数值为 0 时,驱动程序必须应用合理的缺省值。
OFlag 指定访问类型,特殊打开处理,更新类型以及打开的文件的初始状态。 通过对特殊打开处理标志进行逻辑 OR 运算来构造参数值。 这些标志在 fcntl.h 文件中定义,并在以下标志中进行描述。
指定访问权类型的标志

以下 OFlag 参数标志值指定访问权类型:

表 2。 指定访问权类型的标志
描述
O_RDONLY 该文件仅为读取而打开。
0-WRONLY 该文件仅为写入而打开。
0-RDWR 将打开该文件以进行读写操作。
搜索 仅打开该目录以进行搜索。 如果 路径 参数未指向现有目录,那么将忽略此标志。
注: 必须指定其中一个文件访问权值。 请勿同时使用 O_RDONLYO_WRONLYO_RDWR 。 如果未设置任何值,那么将使用 "无" ,并且结果不可预测。
指定特殊打开处理的标志

以下 OFlag 参数标志值指定特殊打开处理:

表 3。 指定特殊打开处理的标志
描述
创建 0 个 如果该文件存在,那么此标志无效,除非在 O_EXCL 标志下另有说明。 如果该文件不存在,那么将创建具有以下特征的常规文件:
  • 该文件的所有者标识设置为该进程的有效用户标识。
  • 如果父目录设置了 SetGroupID 属性 (S_ISGID 位) ,那么文件的组标识将设置为父目录的组标识。 否则,将该文件的组标识设置为呼叫进程的有效组标识。
  • 文件许可权和属性位将设置为 模式 参数的值,修改后如下所示:
    • 清除进程文件方式创建掩码中设置的所有位。 (在 umask 子例程中描述了文件创建掩码。)
    • ISVTX 属性位已清除。

当文件位于加密目录或继承模式中并且调用进程具有打开的密钥库时, open64 子例程使用 O_CREAT 标志打开的文件必须创建加密文件。 这将产生生成随机对称文件加密密钥的效果,将其与用户的公用密钥合并,并将其存储在文件的元 ' ata 中。

O_EFSON

O_CREAT 标志一起,此标志显式地在启用了 EFS 的文件系统中创建加密文件,覆盖继承。 此函数可用于 open64x 子例程。

O_EFSOFF 创建 0 个 标志一起,此标志将显式覆盖继承以创建非加密文件。 此函数可用于 open64x 子例程。
目录 (O_DIRECTORY) 如果 路径 参数未指向目录,那么该子例程不成功。
O_EXCL 如果设置了 O_EXCL创建 0 个 标志,那么在文件存在时打开不成功。
注: 网络文件系统 (NFS) 不完全支持 O_EXCL 标志。 NFS 协议不保证 O_EXCL 标志的设计功能。
O_NSHARE 确保没有任何进程打开此文件,并阻止后续打开。 如果文件位于物理文件系统上并且已打开,那么此打开操作将失败并立即返回,除非 OFlag 参数还指定了 O_DELAY 标志。 此标志仅对物理文件系统有效。
注: 此标志不受 NFS支持。
O_RESHARE 确保没有任何进程打开此文件以进行写入,并阻止后续打开以进行写入。 调用进程可以请求写访问权。 如果文件位于物理文件系统上,并且已打开以使用 O_NSHARE 标志进行写入或打开,那么此打开操作将失败并立即返回,除非 OFlag 参数还指定了 O_DELAY 标志。
注: 此标志不受 NFS支持。
0-RAW 在不持有加密密钥的情况下以原始方式读取或写入加密文件。 此函数可用于 open64x 子例程。
O_DEFER 将打开该文件以进行延迟更新。 在执行 fsync 子例程操作之前,对文件的更改不会反映在永久存储器上。 如果未执行任何 fsync 子例程操作,那么在关闭文件时将废弃这些更改。
注: 此标志不受 NFS 或 JFS2支持,该标志将被悄悄忽略。
注: 此标志导致调页空间支持已修改的页。 在使用此标志之前,请确保有足够的调页空间。
0-无 此标志指定在此打开过程中不应该指定控制终端。
O_TRUNC 如果该文件不存在,那么此标志没有效果。 如果该文件存在,是常规文件,并且使用 O_RDWR 标志或 O_WRONLY 标志成功打开,那么以下所有内容都适用:
  • 该文件的长度将截断为 0。
  • 该文件的所有者和组未更改。
  • 将清除文件方式的 SetUserID 属性。
  • 已清除文件的 SetUserID 属性。
重定向 此标志指定在打开此文件时将对此文件使用直接 i/o。
0-首席信息官 此标志指定在打开文件时将对该文件使用并发 i/o (CIO)。 由于实现并发阅读器和写程序会利用直接 I/O 路径 (具有更具体的需求以提高在文件系统上运行数据库的性能) ,因此如果同时指定这两个选项,那么此标志将覆盖 重定向 标志。 要读取或写入的数据的长度以及文件偏移量必须是页对齐的,才能作为直接 i/o 与并发阅读器和写程序进行传输。

0-首席信息官 标志是互斥的。 如果以任何其他方式打开该文件 (例如,使用 重定向 标志或正常打开该文件) ,那么打开将失败。 如果使用 0-首席信息官 标志打开文件,并且另一个进程以另一种方式打开文件,那么打开将失败。 O_CIO 标志还会阻止 mmap 子例程和 shmat 子例程访问文件。 如果在使用 O_CIO 标志打开的文件上使用了 mmap 子例程和 shmat 子例程,那么会返回 EINVAL

O_CIOR 此标志指定在打开文件时将对该文件使用并发 I/O。 此标志只能与 O_CIO结合使用。 此外,此标志还指定另一个进程可以以只读方式打开文件。 打开文件的所有其他方法都将失败。 此标志仅可用于 open64x() 接口。 其他类型的打开只允许使用低阶 32 位中定义的标志。
O_SNAPSHOT 正在打开的文件包含 JFS2 快照。 使用此文件描述符的后续 read 调用将读取熟快照而不是原始快照块。 快照只能有一个处于活动状态的打开文件描述符。 O_SNAPSHOT 选项仅可用于外部快照。

如果满足下列任何条件,那么 open 子例程将失败:

  • 该文件支持强制记录锁定,并且另一个进程已锁定该文件的一部分。
  • 该文件位于物理文件系统上,并且已使用 O_RESHARE 标志或 O_NSHARE 标志打开该文件。
  • 该文件不允许写访问权。
  • 已打开该文件以进行延迟更新。
用于指定更新类型的标志

对于为写访问权打开的常规文件,程序可以请求对何时应该永久进行更新进行一些控制。 以下 OFlag 参数值指定所执行的更新类型:

表 4。 用于指定更新类型的标志
描述
O_SYNC 如果设置,那么对常规文件的更新以及对块设备的写操作都是同步更新。 文件更新是由以下子例程执行的:
  • fclear
  • ftruncate
  • openO_TRUNC
  • write

从执行同步更新的子例程返回 (任何先前的子例程,当设置了 O_SYNC 标志时) ,程序将确保文件的所有数据都已写入永久存储器,即使文件也已打开以进行延迟更新。

O_DSYNC 如果设置了此参数,那么会将文件数据以及检索文件数据所需的所有文件系统元数据写入到其永久存储位置。 不需要文件属性 (例如访问或修改时间) 来检索文件数据,因此,在上述子例程返回之前,不保证将这些属性写入其永久存储位置。 ( O_SYNC 描述中列出的子例程。)
o_sync | o_dsync 如果同时设置了这两个标志,那么该文件的数据以及该文件的所有元数据 (包括访问时间) 都将写入其永久存储位置。
O_RSYNC 此标志与 O_SYNC同步 (_S)结合使用,它会将其写操作行为扩展为读操作。 例如,如果同时设置了 O_SYNCR_SYNC ,那么在将文件的数据和文件的所有元数据 (包括访问时间) 写入其永久存储位置之前,将不会返回读操作。
用于定义打开文件初始状态的标志

以下 OFlag 参数标志值定义打开的文件的初始状态:

表 5。 用于定义打开文件初始状态的标志
描述
O_APPEND 在执行每个写操作之前,将文件指针设置为文件的结尾。
O_DELAY 指定如果 open 子例程由于无法授予对 O_RSHARE 标志或 O_NSHARE 标志所要求的物理文件系统的访问权而无法成功,那么进程块而不是返回 ETXTBSY 错误代码。
O_NDELAY 在没有延迟的情况下打开。
O_NONBLOCK 指定 open 子例程不应阻止。

除了 readwrite 子例程返回的值以外, O_NDELAY 标志和 O_NONBLOCK 标志是相同的。 这些标志意味着进程不会阻止对象的状态,而是在输入或输出到常规文件或块设备时进行阻止。

仅当与 O_NSHAREO_RESHARE 标志一起使用时, O_DELAY 标志才相关。 它与 O_NDELAYO_NONBLOCK 标志不相关。

关于 OFlag 参数标志的一般说明

创建 0 个 标志的效果是即时的,即使使用 0-DEFER 标志打开该文件也是如此。

使用 O_NSHARE 标志或 O_RESHARE 标志在物理文件系统上打开文件时,如果该文件已打开且具有冲突访问权,那么可能会发生以下情况:

  • 如果 O_DELAY 标志为 clear (缺省值) ,那么 open 子例程不成功。
  • 如果设置了 O_DELAY 标志,那么 open 子例程将阻塞,直到没有冲突打开为止。 对于使用 O_DELAY 标志的进程,不存在死锁检测。

在已使用 O_NSHARE 标志打开的物理文件系统上打开文件时,可能会发生下列情况:

  • 如果 O_DELAY 标志为 clear (缺省值) ,那么打开操作将立即失败。
  • 如果设置了 O_DELAY 标志,那么打开块直到没有冲突的打开为止。

当使用 0-RDWR0-WRONLYO_TRUNC 标志打开文件,并且该文件已使用 O_RESHARE 标志打开时:

  • 如果 O_DELAY 标志为 clear (缺省值) ,那么打开操作将立即失败。
  • 如果设置了 O_DELAY 标志,那么打开块直到没有冲突的打开为止。

使用 O_REDONLY 标志打开 "先入先出" (FIFO) 时,可能会发生以下情况:

  • 如果清除 O_NDELAYO_NONBLOCK 标志,那么将打开块,直到进程打开文件以进行写入。 如果文件已打开进行写入 (即使是由调用进程) ,那么 open 子例程将立即返回。
  • 如果设置了 O_NDELAY 标志或 O_NONBLOCK 标志,那么即使没有任何进程打开 FIFO 以进行写入,打开也会立即成功。

在使用 0-WRONLY 标志打开 FIFO 时,可能会发生以下情况:

  • 如果 O_NDELAYO_NONBLOCK 标志未选中 (缺省值) ,那么打开的块将一直到进程打开文件进行读取为止。 如果文件已打开进行写入 (即使是由调用进程) ,那么 open 子例程将立即返回。
  • 如果设置了 O_NDELAY 标志或 O_NONBLOCK 标志,那么如果当前没有进程打开文件进行读取,那么 open 子例程将返回错误。

当打开支持非阻塞打开的块特殊文件或字符特殊文件 (例如终端设备) 时,可能会发生以下情况:

  • 如果取消选中 O_NDELAYO_NONBLOCK 标志 (缺省值) ,那么打开的块将一直显示到设备就绪或可用为止。
  • 如果设置了 O_NDELAY 标志或 O_NONBLOCK 标志,那么 open 子例程将返回而不等待设备就绪或可用。 设备的后续行为是特定于设备的。

有关特定设备上的 O_NDELAYO_RSHAREO_NSHAREO_DELAY 标志的影响 (如果有) 的任何其他信息都记录在与设备类型相关的特殊文件的描述中。

如果路径引用了 STREAMS 文件,那么可以使用 O_RDONLYO_WRONLYO_RDWRO_NONBLOCK OR 构造 oflag 。 其他标志值不适用于 STREAMS 设备,并且对这些设备没有影响。 值 O_NONBLOCK 影响 STREAMS 驱动程序的操作以及应用于与 STREAMS 文件关联的文件描述符的某些功能。 对于 STREAMS 驱动程序, O_NONBLOCK 的实现是特定于设备的。

如果路径指定伪终端设备的控制器端,那么未指定 open 是否锁定工作程序端,以便无法将其打开。 在打开工作程序端之前,可移植应用程序必须调用 unlockpt

搜索 标志的值与 EXEC 标志的值相同。 从 AIX® 7.1开始,将 O_EXEC 标志传递到打开的目录的程序可能会失败,因为打开的代码还将检查该目录的搜索许可权。

在类型为 off_t 的对象中可以正确表示的最大值将被确定为打开文件描述中的最大偏移量。

返回值

在成功完成时,将返回文件描述符 (非负整数)。 否则,返回值为-1,不创建或修改任何文件,并设置全局变量 "errno以指示错误。

错误代码

openopenat openxopenxatopen64open64atopen64xopen64xatcreat 子例程不成功,如果满足以下一个或多个条件,那么不会打开指定的文件:

表 6。 错误代码
描述
EACCES 发生了下列其中一个错误:
  • 该文件已存在,并且 OFlag 参数指定的访问类型被拒绝。
  • 对于由 路径 参数指定的路径前缀的组件,搜索许可权被拒绝。 由于安全安装,访问可能被拒绝。
  • 该文件不存在,并且对要创建的文件的父目录的写许可权被拒绝。
  • 指定了 O_TRUNC 标志,并且拒绝了写许可权。
EAGAIN O_TRUNC 标志已设置,并且指定的文件包含另一个进程拥有的记录锁定。
EDQUOT 无法扩展用于放置新链接的条目的目录,或者无法为文件分配索引节点,因为包含该目录的文件系统中的磁盘块或索引节点的用户或组配额已耗尽。
EEXIST 设置了 创建 0 个O_EXCL 标志,并且指定的文件存在。
EFBIG 已尝试写入超过进程文件限制或最大文件大小的文件。 如果用户在执行进程之前设置了环境变量 XPG_SUS_ENV=ON ,那么当超过进程的文件大小限制时,将向进程发布 SIGXFSZ 信号。
EAGAIN open 子例程期间捕获到信号。
EIO path 参数指定 STREAMS 文件,并发生挂起或错误。
EISDIR 指定的文件是目录,并且需要写访问权 (在 OFlag 参数中设置 0-WRONLY0-RDWR 标志)。
电子文件 已达到每个进程的打开文件描述符数的系统限制 (OPEN_MAX)。
ENAMETOOLONG 路径 参数的长度超过系统限制 (PATH_MAX); 或者路径名组件的长度超过 NAME_MAX ,并且 _POSIX_NO_TRUNC 生效。
ENFILE 系统文件表已满。
ENOENT 未设置 创建 0 个 标志,并且指定的文件不存在; 或者未设置 创建 0 个 标志,并且路径前缀不存在,或者 路径 参数指向空字符串。
ENOTDIR 设置了 目录 (O_DIRECTORY) 标志,并且 "路径" 参数未指向现有目录。
ENOMEM 路径 参数对 STREAMS 文件进行命名,并且系统无法分配资源。
ENOSPC 无法扩展将包含新文件的目录或文件系统。
ENOSR Path 参数对基于 STREAMS 的文件进行命名,并且系统无法分配 STREAM。
ENOTDIR 路径 组件指定的路径前缀的组件不是目录。
ENXIO 发生了下列其中一个错误:
  • 指定的文件是字符特殊文件或块特殊文件,并且与此特殊文件相关联的设备不存在。
  • 指定的文件是多路复用的特殊文件,并且通道号不在有效范围内,或者没有更多通道可用。
  • 设置了 O_DELAY 标志或 O_NONBLOCK 标志,指定的文件是 FIFO ,设置了 O_WRONLY 标志,并且没有进程打开文件进行读取。
Eoverflow 在 JFS2中的 32 位内核上打开了一个大于 1 太字节的文件。 确切的最大大小在 MAX_FILESIZE 中指定,可以使用 pathconf 系统调用来获取。 任何大于不能在 32 位内核上打开的文件,但可以在 64 位内核上创建和打开的文件。
EROFS 指定的文件位于只读文件系统上,并且需要具有写访问权 ( 0-WRONLY0-RDWR创建 0 个 (如果文件不存在) ,或者在 OFlag 参数中设置了 O_TRUNC 标志)。
ETXTBSY 文件位于物理文件系统上,并且已以排除此打开的方式 (使用 O_RESHAREO_NSHARE 标志) 打开; 或者 O_NSHAREO_RESHARE 标志是在设置了 O_NDELAY 标志的情况下请求的,并且在物理文件系统上存在冲突的打开。
ENOATTR 在此过程中未装入任何密钥库。
ESAD 对于新文件的所有者,密钥库中没有可用的密钥。
Eoverflow opencreat 进行了调用,并且该文件已存在,并且其大小大于 OFF_MAX ,并且未设置 O_LARGEFILE 标志。

如果下列其中一个子例程为 true ,那么 openopenxopen64xcreat 子例程将失败:

表 7。 错误代码
描述
EFAULT 路径 参数指向进程的已分配地址空间之外的位置。
EINVAL OFlag 参数的值是无效的。
ELOOP 在转换 路径 参数时迂到过多的符号链接。
ETXTBSY 路径 参数指定的文件是当前正在执行的纯过程 (共享文本) 文件,并且在 OFlag 参数中设置了 0-WRONLY0-RDWR 标志。

openatopenxatopen64atopen64xat 子例程不成功,如果满足以下一个或多个条件,那么不会打开指定的文件:

表 8。 错误代码
描述
EACCES DirFileDescriptor参数指向的目录未使用O_SEARCH标志打开,并且该目录的搜索权限被拒绝。
EBADF 路径参数没有指定绝对路径,DirFileDescriptor参数既不是AT_FDCWD,也不是有效的文件描述符。
ENOTDIR 路径参数没有指定绝对路径,"DirFileDescriptor参数既不是 "AT_FDCWD,也不是与目录相关的文件描述符。