open, creat − 用 来 打 开 和 创 建 一 个 文 件 或 设 备
#includ e
<sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int
open(const char *pathname, int
flags);
int open(const char *pathname, int
flags, mode_t mode)
int creat(const char *pathname, mode_t
mode);
open() 通 常 用 于 将 路 径 名 转 换 为 一 个 文 件 描 述 符 (一 个 非 负 的 小 整 数 , 在 read , write 等 I/O操 作 中 将 会 被 使 用 ). 当 open() 调 用 成 功 , 它 会 返 回 一 个 新 的 文 件 描 述 符 (永 远 取 未 用 描 述 符 的 最 小 值 ). 这 个 调 用 创 建 一 个 新 的 打 开 文 件 , 即 分 配 一 个 新 的 独 一 无 二 的 文 件 描 述 符 , 不 会 与 运 行 中 的 任 何 其 他 程 序 共 享 (但 可 以 通 过 fork (2) 系 统 调 用 实 现 共 享 ). 这 个 新 的 文 件 描 述 符 在 其 后 对 打 开 文 件 操 作 的 函 数 中 使 用 .(参 考 fcntl(2)). 文 件 的 读 写 指 针 被 置 于 文 件 头
参
数 flags 是 通 过
O_RDONLY, O_WRONLY 或 O_RDWR
(指 明 文 件 是 以
只 读 , 只 写 或 读
写 方 式 打 开 的 )
与 下 面 的 零 个
或 多 个 可 选 模
式 按 位 -or 操 作
得 到 的 :
O_CREAT
若 文 件 不 存 在 将 创 建 一 个 新 文 件 . 新 文 件 的 属 主 (用 户 ID) 被 设 置 为 此 程 序 的 有 效 用 户 的 ID. 同 样 文 件 所 属 分 组 也 被 设 置 为 此 程 序 的 有 效 分 组 的 ID 或 者 上 层 目 录 的 分 组 ID (这 依 赖 文 件 系 统 类 型 ,装 载 选 项 和 上 层 目 录 的 模 式 , 参 考 ,在 mount(8) 中 描 述 的 ext2 文 件 系 统 的 装 载 选 项 bsdgroups 和 sysvgroups )
|
O_EXCL |
通 过 O_CREAT, 生 成 文 件 , 若 文 件 已 经 存 在 , 则 open 出 错 , 调 用 失 败 . 若 是 存 在 符 号 联 接 , 将 会 把 它 的 联 接 指 针 的 指 向 文 件 忽 略 . O_EXCL is broken on NFS file systems, programs which rely on it for performing locking tasks will contain a race condition. The solution for performing atomic file locking using a lockfile is to create a unique file on the same fs (e.g., incorporating hostname and pid), use link(2) to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its link count has increased to 2, in which case the lock is also successful. |
O_NOCTTY
假 如 pathname 引 用 一 个 终 端 设 备 — 参 考 tty(4) — 即 使 进 程 没 有 控 制 终 端 ,这 个 终 端 也 不 会 变 成 进 程 的 控 制 终 端 .
O_TRUNC
假 如 文 件 已 经 存 在 , 且 是 一 个 普 通 文 件 ,打 开 模 式 又 是 可 写 (即 文 件 是 用 O_RDWR 或 O_WRONLY 模 式 打 开 的 ) , 就 把 文 件 的 长 度 设 置 为 零 , 丢 弃 其 中 的 现 有 内 容 .若 文 件 是 一 个 FIFO 或 终 端 设 备 文 件 , O_TRUNC 标 志 被 忽 略 . 其 他 O_TRUNC 的 作 用 是 不 具 体 指 定 的 (在 许 多 Linux 版 本 中 , 通 常 会 被 忽 略 , 其 他 的 一 些 版 本 将 返 回 一 个 错 误 )
O_APPEND
文 件 以 追 加 模 式 打 开 . 在 写 以 前 , 文 件 读 写 指 针 被 置 在 文 件 的 末 尾 . as if with lseek. O_APPEND may lead to corrupted files on NFS file systems if more than one process appends data to a file at once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can’t be done without a race condition.
O_NONBLOCK 或 O_NDELAY
打 开 (open) 文 件 可 以 以 非 块 (non-blocking) 模 式 打 开 . 此 时 文 件 并 没 有 打 开 , 也 不 能 使 用 返 回 的 文 件 描 述 符 进 行 后 续 操 作 , 而 是 使 调 用 程 序 等 待 . 此 模 式 是 为 了 FIFO (命 名 管 道 ) 的 处 理 , 参 考 fifo(4). 这 种 模 式 对 除 了 FIFO 外 没 有 任 何 影 响 .
|
O_SYNC |
打 开 文 件 实 现 I/O 的 同 步 . 任 何 通 过 文 件 描 述 符 对 文 件 的 write 都 会 使 调 用 的 进 程 中 断 , 直 到 数 据 被 真 正 写 入 硬 件 中 . 其 他 , 参 考 RESTRICTIONS. |
O_NOFOLLOW
假 如
pathname 是 一 个 符 号
联 接 , 则 打 开 失
败 . 这 是 FreeBSD 的 扩
充 , 从 2.1.126 版 本 以
来 被 引 入 到 Linux 中
来 . 从 glibc2.0.100 库 以 来
, 头 文 件 中 包 括
了 这 个 参 数 的
定 义 ;
kernel 2.1.126 以 前 将 忽 略
它 的 使 用 .
O_DIRECTORY
假 如 pathname 不 是 目 录 , 打 开 就 失 败 . 这 个 参 数 是 Linux 特 有 的 , 在 kernel 2.1.126 中 加 入 , 为 了 避 免 在 调 用 FIFO 或 磁 带 设 备 时 的 denial-of-service 问 题 , 但 是 不 应 该 在 执 行 opendir 以 外 使 用 .
O_LARGEFILE
在 32位 系 统 中 支 持 大 文 件 系 统 , 允 许 打 开 那 些 用 31位 都 不 能 表 示 其 长 度 的 大 文 件 .
在 文 件 打 开 后 , 这 些 可 选 参 数 可 以 通 过 fcntl 来 改 变 .
在 新 文 件 被 创 建 时 , 参 数 mode 具 体 指 明 了 使 用 权 限 . 他 通 常 也 会 被 umask 修 改 . 所 以 一 般 新 建 文 件 的 权 限 为 (mode & ~umask). 注 意 模 式 只 被 应 用 于 将 来 对 这 新 文 件 的 使 用 中 ; open 调 用 创 建 一 个 新 的 只 读 文 件 , 但 仍 将 返 回 一 个 可 读 写 文 件 描 述 符 .
后
面 是 一 些 mode 的
具 体 参 数 :
S_IRWXU
00700 允 许 文 件 的 属 主 读 , 写 和 执 行 文 件
S_IRUSR (S_IREAD)
00400 允 许 文 件 的 属 主 读 文 件
S_IWUSR (S_IWRITE)
00200 允 许 文 件 的 属 主 写 文 件
S_IXUSR (S_IEXEC)
00100 允 许 文 件 的 属 主 执 行 文 件
S_IRWXG
00070 允 许 文 件 所 在 的 分 组 读 , 写 和 执 行 文 件
S_IRGRP
00040 允 许 文 件 所 在 的 分 组 读 文 件
S_IWGRP
00020 允 许 文 件 所 在 的 分 组 写 文 件
S_IXGRP
00010 允 许 文 件 所 在 的 分 组 执 行 文 件
S_IRWXO
00007 允 许 其 他 用 户 读 , 写 和 执 行 文 件
S_IROTH
00004 允 许 其 他 用 户 读 文 件
S_IWOTH
00002 允 许 其 他 用 户 写 文 件
S_IXOTH
00001 允 许 其 他 用 户 执 行 文 件
mode 只 有 当 在 flags 中 使 用 O_CREAT 时 才 有 效 , 否 则 被 忽 略 .
creat 相 当 于 open 的 参 数 flags 等 于 O_CREAT|O_WRONLY|O_TRUNC.
open 和 creat 都 返 回 一 个 新 的 文 件 描 述 符 (若 是 有 错 误 发 生 返 回 −1 ,并 在 errno 设 置 错 误 信 息 ). 注 意 open 可 以 打 开 设 备 专 用 文 件 , 但 是 creat 不 能 创 建 ,需 要 用 mknod(2) 来 代 替 .
On NFS file systems with UID mapping enabled, open may return a file descriptor but e.g. read(2) requests are denied with EACCES. This is because the client performs open by checking the permissions, but UID mapping is performed by the server upon read and write requests.
若 文 件 是 新 建 立 的 , 他 的 atime(上 次 访 问 时 间 ), ctime(创 建 时 间 ), mtime(修 改 时 间 ) 都 被 修 改 为 当 前 时 间 , 上 层 目 录 的 atime , ctime 也 被 同 样 修 改 . 其 他 的 , 假 如 文 件 是 由 O_TRUNC 参 数 修 改 的 ,它 的 ctime , mtime 域 也 被 设 置 为 当 前 时 间 .
|
EEXIST |
参 数 O_CREAT and O_EXCL 被 使 用 ,但 是 文 件 ( pathname )已 经 存 在 . | ||
|
EISDIR |
文 件 名 ( pathname ) 是 一 个 目 录 , 而 又 涉 及 到 写 操 作 . | ||
|
EACCES |
访 问 请 求 不 允 许 (权 限 不 够 ) , 在 文 件 名 ( pathname )中 有 一 目 录 不 允 许 搜 索 (没 有 执 行 权 限 ) , 或 者 文 件 还 不 存 在 且 对 上 层 目 录 的 写 操 作 又 不 允 许 . |
ENAMETOOLONG
文 件 名 ( pathname ) 太 长 了
|
ENOENT |
目 录 ( pathname ) 不 存 在 或 者 是 一 个 悬 空 的 符 号 联 接 . |
ENOTDIR
pathname 不 是 一 个 子 目 录
|
ENXIO |
使 用 O_NONBLOCK | O_WRONLY, 命 名 的 文 件 是 FIFO , 所 读 文 件 还 没 有 打 开 的 文 件 , 或 者 , 打 开 一 个 设 备 专 用 文 件 而 相 应 的 设 备 不 存 在 | ||
|
ENODEV |
文 件 ( pathname ) 引 用 了 一 个 设 备 专 用 文 件 , 而 相 应 的 设 备 又 不 存 在 . (这 是 linux kernel 的 一 个 bug - ENXIO 一 定 会 被 返 回 .) | ||
|
EROFS |
文 件 ( pathname ) 是 一 个 只 读 文 件 , 又 有 写 操 作 被 请 求 . |
ETXTBSY
文 件 ( pathname ) 是 一 个 正 在 被 执 行 的 可 执 行 文 件 ,又 有 写 操 作 被 请 求 .
|
EFAULT |
pathname 在 一 个 你 不 能 访 问 的 地 址 空 间 . | ||
|
ELOOP |
在 分 解 pathname 时 , 遇 到 太 多 符 号 联 接 或 者 指 明 O_NOFOLLOW 但 是 pathname 是 一 个 符 号 联 接 | ||
|
ENOSPC |
pathname 将 要 被 创 建 ,但 是 设 备 又 没 有 空 间 储 存 pathname 文 件 了 | ||
|
ENOMEM |
可 获 得 的 核 心 内 存 (kernel memory) 不 够 | ||
|
EMFILE |
程 序 打 开 的 文 件 数 已 经 达 到 最 大 值 了 | ||
|
ENFILE |
系 统 打 开 的 总 文 件 数 已 经 达 到 了 极 限 |
SVr4, SVID, POSIX, X/OPEN, BSD 4.3 The O_NOFOLLOW and O_DIRECTORY flags are Linux-specific. One may have to define the _GNU_SOURCE macro to get their definitions.
There are many infelicities in the protocol underlying NFS, affecting amongst others O_SYNC and O_NDELAY.
POSIX provides for three different variants of synchronised I/O, corresponding to the flags O_SYNC, O_DSYNC and O_RSYNC. Currently (2.1.130) these are all synonymous under Linux.
read(2), write(2), fcntl(2), close(2), link(2), mknod(2), mount(2), stat(2), umask(2), unlink(2), socket(2), fopen(3), fifo(4)
Daniel <badlong [AT] 163.com>
2002/01/10