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参数关联的目录,而不是当前工作目录。 同样, openxat, open64at或 open64xat 子例程分别与 openx, open64或 open64x 子例程等效,其方式与 openat 和 open相同。
open, openx和 creat 子例程在 Path 参数指定的文件与文件描述符之间建立连接。 打开的文件描述符由后续 I/O 子例程 (例如 read 和 write) 用于访问该文件。
openx 子例程与 open 子例程相同,添加了供设备驱动程序使用的 Extension 参数。 creat 子例程等同于设置了 O_WRONLY, O_CREAT和 O_TRUNC 标志的 open 子例程。
返回的文件描述符是先前未对该进程打开的最低文件描述符。 任何进程都不能同时打开超过 OPEN_MAX 个文件描述符。
文件偏移量 (标记文件中的当前位置) 被设置为文件的开头。 新的文件描述符设置为在 exec 子例程之间保持打开状态。
open64 和 creat64 子例程等同于 open 和 creat 子例程,只是在与返回的文件描述符相关联的打开文件描述中设置了 O_LARGEFILE 标志。 此标志允许访问大于 OFF_MAX 的文件。 如果调用者尝试打开大于 OFF_MAX 且未设置 O_LARGEFILE 的文件,那么打开将失败,并且 errno 将设置为 EOVERFLOW。
在启用了大文件的编程环境中, open 将重新定义为 open64 , creat 将重新定义为 creat64。
open64x 子例程在加密文件系统 (EFS) 中创建和访问加密文件。 open64x 子例程类似于 openx 子例程,通过修改 OFlag 参数,将其更新为 64 位数量。
如果 "openat、"openxat、"open64at"或 "open64xat"子程序中的DirFileDescriptor参数在打开时未使用O_SEARCH打开标志,则该子程序会通过使用目录的当前权限来检查是否允许对该目录进行目录搜索。 如果该目录是使用 O_SEARCH 打开标志打开的,那么子例程不会对该目录执行检查。
参数
| 项 | 描述 |
|---|---|
| DirFileDescriptor | 指定打开的目录的文件描述符。 |
| 路径 | 指定要打开的文件。 如果指定了DirFileDescriptor,且 Path 是相对路径名,则Path将被视为相对于DirFileDescriptor 指定的目录。 |
| 方式 | 指定要创建的文件的读许可权,写许可权和执行许可权 (由 创建 0 个 标志请求)。 如果该文件已存在,那么将忽略此参数。 Mode 参数通过对 <sys/mode.h> 文件中定义的以下一个或多个值进行逻辑 OR 运算来构造:
下列属性仅适用于直接可执行的文件。 当应用于可执行文本文件 (例如 shell 脚本和 awk 脚本) 时,它们没有意义。
|
| 扩展名 | 提供与需要其他信息或返回其他状态的字符设备驱动程序的通信。 每个驱动程序都以与设备相关的方式将 扩展 参数解释为值或指向通信区域的指针。 当 扩展 参数值为 0 时,驱动程序必须应用合理的缺省值。 |
| OFlag | 指定访问类型,特殊打开处理,更新类型以及打开的文件的初始状态。 通过对特殊打开处理标志进行逻辑 OR 运算来构造参数值。 这些标志在 fcntl.h 文件中定义,并在以下标志中进行描述。 |
- 指定访问权类型的标志
以下 OFlag 参数标志值指定访问权类型:
表 2。 指定访问权类型的标志 项 描述 O_RDONLY 该文件仅为读取而打开。 0-WRONLY 该文件仅为写入而打开。 0-RDWR 将打开该文件以进行读写操作。 搜索 仅打开该目录以进行搜索。 如果 路径 参数未指向现有目录,那么将忽略此标志。 注: 必须指定其中一个文件访问权值。 请勿同时使用 O_RDONLY, O_WRONLY或 O_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
- open 与 O_TRUNC
- write
从执行同步更新的子例程返回 (任何先前的子例程,当设置了 O_SYNC 标志时) ,程序将确保文件的所有数据都已写入永久存储器,即使文件也已打开以进行延迟更新。
O_DSYNC 如果设置了此参数,那么会将文件数据以及检索文件数据所需的所有文件系统元数据写入到其永久存储位置。 不需要文件属性 (例如访问或修改时间) 来检索文件数据,因此,在上述子例程返回之前,不保证将这些属性写入其永久存储位置。 ( O_SYNC 描述中列出的子例程。) o_sync | o_dsync 如果同时设置了这两个标志,那么该文件的数据以及该文件的所有元数据 (包括访问时间) 都将写入其永久存储位置。 O_RSYNC 此标志与 O_SYNC 或 同步 (_S)结合使用,它会将其写操作行为扩展为读操作。 例如,如果同时设置了 O_SYNC 和 R_SYNC ,那么在将文件的数据和文件的所有元数据 (包括访问时间) 写入其永久存储位置之前,将不会返回读操作。 - 用于定义打开文件初始状态的标志
以下 OFlag 参数标志值定义打开的文件的初始状态:
表 5。 用于定义打开文件初始状态的标志 项 描述 O_APPEND 在执行每个写操作之前,将文件指针设置为文件的结尾。 O_DELAY 指定如果 open 子例程由于无法授予对 O_RSHARE 标志或 O_NSHARE 标志所要求的物理文件系统的访问权而无法成功,那么进程块而不是返回 ETXTBSY 错误代码。 O_NDELAY 在没有延迟的情况下打开。 O_NONBLOCK 指定 open 子例程不应阻止。 除了 read 和 write 子例程返回的值以外, O_NDELAY 标志和 O_NONBLOCK 标志是相同的。 这些标志意味着进程不会阻止对象的状态,而是在输入或输出到常规文件或块设备时进行阻止。
仅当与 O_NSHARE 或 O_RESHARE 标志一起使用时, O_DELAY 标志才相关。 它与 O_NDELAY 和 O_NONBLOCK 标志不相关。
- 关于 OFlag 参数标志的一般说明
创建 0 个 标志的效果是即时的,即使使用 0-DEFER 标志打开该文件也是如此。
使用 O_NSHARE 标志或 O_RESHARE 标志在物理文件系统上打开文件时,如果该文件已打开且具有冲突访问权,那么可能会发生以下情况:
- 如果 O_DELAY 标志为 clear (缺省值) ,那么 open 子例程不成功。
- 如果设置了 O_DELAY 标志,那么 open 子例程将阻塞,直到没有冲突打开为止。 对于使用 O_DELAY 标志的进程,不存在死锁检测。
返回值
在成功完成时,将返回文件描述符 (非负整数)。 否则,返回值为-1,不创建或修改任何文件,并设置全局变量 "errno以指示错误。
错误代码
open,openat openx, openxat, open64, open64at, open64x, open64xat和 creat 子例程不成功,如果满足以下一个或多个条件,那么不会打开指定的文件:
| 项 | 描述 |
|---|---|
| EACCES | 发生了下列其中一个错误:
|
| EAGAIN | O_TRUNC 标志已设置,并且指定的文件包含另一个进程拥有的记录锁定。 |
| EDQUOT | 无法扩展用于放置新链接的条目的目录,或者无法为文件分配索引节点,因为包含该目录的文件系统中的磁盘块或索引节点的用户或组配额已耗尽。 |
| EEXIST | 设置了 创建 0 个 和 O_EXCL 标志,并且指定的文件存在。 |
| EFBIG | 已尝试写入超过进程文件限制或最大文件大小的文件。 如果用户在执行进程之前设置了环境变量 XPG_SUS_ENV=ON ,那么当超过进程的文件大小限制时,将向进程发布 SIGXFSZ 信号。 |
| EAGAIN | 在 open 子例程期间捕获到信号。 |
| EIO | path 参数指定 STREAMS 文件,并发生挂起或错误。 |
| EISDIR | 指定的文件是目录,并且需要写访问权 (在 OFlag 参数中设置 0-WRONLY 或 0-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 | 发生了下列其中一个错误:
|
| Eoverflow | 在 JFS2中的 32 位内核上打开了一个大于 1 太字节的文件。 确切的最大大小在 MAX_FILESIZE 中指定,可以使用 pathconf 系统调用来获取。 任何大于不能在 32 位内核上打开的文件,但可以在 64 位内核上创建和打开的文件。 |
| EROFS | 指定的文件位于只读文件系统上,并且需要具有写访问权 ( 0-WRONLY, 0-RDWR, 创建 0 个 (如果文件不存在) ,或者在 OFlag 参数中设置了 O_TRUNC 标志)。 |
| ETXTBSY | 文件位于物理文件系统上,并且已以排除此打开的方式 (使用 O_RESHARE 或 O_NSHARE 标志) 打开; 或者 O_NSHARE 或 O_RESHARE 标志是在设置了 O_NDELAY 标志的情况下请求的,并且在物理文件系统上存在冲突的打开。 |
| ENOATTR | 在此过程中未装入任何密钥库。 |
| ESAD | 对于新文件的所有者,密钥库中没有可用的密钥。 |
| Eoverflow | 对 open 和 creat 进行了调用,并且该文件已存在,并且其大小大于 OFF_MAX ,并且未设置 O_LARGEFILE 标志。 |
如果下列其中一个子例程为 true ,那么 open, openx, open64x和 creat 子例程将失败:
| 项 | 描述 |
|---|---|
| EFAULT | 路径 参数指向进程的已分配地址空间之外的位置。 |
| EINVAL | OFlag 参数的值是无效的。 |
| ELOOP | 在转换 路径 参数时迂到过多的符号链接。 |
| ETXTBSY | 由 路径 参数指定的文件是当前正在执行的纯过程 (共享文本) 文件,并且在 OFlag 参数中设置了 0-WRONLY 或 0-RDWR 标志。 |
openat, openxat, open64at和 open64xat 子例程不成功,如果满足以下一个或多个条件,那么不会打开指定的文件:
| 项 | 描述 |
|---|---|
| EACCES | DirFileDescriptor参数指向的目录未使用O_SEARCH标志打开,并且该目录的搜索权限被拒绝。 |
| EBADF | 路径参数没有指定绝对路径,DirFileDescriptor参数既不是AT_FDCWD,也不是有效的文件描述符。 |
| ENOTDIR | 路径参数没有指定绝对路径,"DirFileDescriptor参数既不是 "AT_FDCWD,也不是与目录相关的文件描述符。 |