了解Linux命令打开

概要

#include << A HREF =“file:/usr/include/sys/types.h”> sys / types.h> #include << A HREF =“file:/usr/include/sys/stat.h”> sys / stat.h> #include << A HREF =“file:/usr/include/fcntl.h”> 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()系统调用linux 命令用于将路径名转换为文件描述符(用于后续I / O的小型非负整数,如读取写入等)。 当调用成功时,返回的文件描述符将是当前未打开的最低文件描述符。 此调用会创建一个新的打开文件,不会与任何其他进程共享。 (但共享打开的文件可能通过fork (2)系统调用产生)。新的文件描述符被设置为在exec函数中保持打开状态(请参阅fcntl (2))。 文件偏移量被设置为文件的开头。

参数标志O_RDONLYO_WRONLYO_RDWR中的一个, 它们分别请求以只读,只写或读/写方式打开文件,按位 'd分别具有以下零个或多个:

O_CREAT

如果文件不存在,它将被创建。 文件的所有者(用户标识)被设置为进程的有效用户标识。 组所有权(组ID)设置为进程的有效组标识或父目录的组标识(取决于文件系统类型和安装选项,以及父目录的模式,请参阅,例如,安装如mount (8)中所述,选择ext2文件系统的bsdgroupssysvgroups )。

O_EXCL

当与O_CREAT一起使用时,如果该文件已经存在,则是错误,并且打开将失败。 在这种情况下,存在一个符号链接,无论它指向何处。 O_EXCLNFS文件系统上被破坏,依靠它执行锁定任务的程序将包含竞争条件。 使用lockfile执行原子文件锁定的解决方案是在同一个fs上创建一个唯一文件(例如,包含hostname和pid),使用link (2)创建一个到lockfile的链接。 如果link()返回0,则锁定成功。 否则,在唯一文件上使用stat (2)来检查其链接计数是否增加到2,在这种情况下,锁定也是成功的。

O_NOCTTY

如果路径名指的是终端设备,请参见tty (4)---即使进程没有控制终端,它也不会成为进程的控制终端。

O_TRUNC

如果文件已经存在并且是一个常规文件,并且打开模式允许写入(即,是O_RDWR或O_WRONLY),则它将被截断为长度0.如果文件是FIFO或终端设备文件,则忽略O_TRUNC标志。 否则,O_TRUNC的效果未指定。 (在许多Linux 版本中 ,它将被忽略;在其他版本上,它将返回一个错误。)

O_APPEND

该文件以附加模式打开。 在每次写入之前,文件指针位于文件的末尾,就像使用lseek一样 。 如果多个进程一次将数据附加到文件,则O_APPEND可能会导致NFS文件系统上的文件损坏。 这是因为NFS不支持附加到文件,因此客户端内核必须对其进行模拟,这在没有竞争条件的情况下不能完成。

O_NONBLOCKO_NDELAY

如果可能,文件以非阻塞模式打开。 对于返回的文件描述符的开放或后续操作都不会导致调用进程等待。 有关FIFO(命名管道)的处理,另请参阅fifo (4)。 此模式不需要对除FIFOs以外的文件有任何影响。

O_SYNC

该文件为同步I / O打开。 结果文件描述符上的任何操作都会阻止调用进程,直到数据被物理写入底层硬件。 尽管如此,请参阅下面的限制。

O_NOFOLLOW

如果路径名是符号链接,则打开失败。 这是一个FreeBSD扩展,它在2.1.126版本中加入了Linux。 路径名早期组件中的符号链接仍将被遵循。 glibc 2.0.100及更高版本的头文件包含此标志的定义; 如果使用的话,2.1.126之前的内核将忽略它

O_DIRECTORY

如果路径名不是目录,则导致打开失败。 该标志是特定于Linux的标志,并在内核版本2.1.126中添加,以避免在FIFO或磁带设备上调用opendir (3)时出现拒绝服务问题,但不应在opendir的实现之外使用。

O_DIRECT

尽量减少I / O对这个文件的缓存效应。 一般而言,这会降低性能,但在特殊情况下非常有用,例如应用程序执行自己的缓存时。 文件I / O直接进入/来自用户空间缓冲区。 I / O是同步的,即在完成读取 (2)或写入 (2)系统调用时,保证数据已被传输。 传输大小以及用户缓冲区和文件偏移的对齐方式都必须是文件系统逻辑块大小的倍数。
这个标志在许多类Unix系统上受到支持; 在内核版本2.4.10的Linux下添加了支持。
原始 (8)中描述了用于块设备的语义上相似的接口。

O_ASYNC

当输入或输出成为可能时,生成一个信号(默认为SIGIO,但可以通过fcntl (2)更改此文件描述符。 该功能仅适用于终端,伪终端和套接字。 有关更多详细信息,请参阅fcntl (2)。

O_LARGEFILE

在支持大文件系统的32位系统上,允许打开其大小不能用31位表示的文件。

文件打开后,可以使用fcntl修改其中一些可选标志。

参数模式指定在创建新文件的情况下使用的权限。 它以通常的方式被进程的umask修改:创建的文件的权限是(mode&〜umask) 。 请注意,此模式仅适用于新创建的文件的未来访问; 创建只读文件的公开调用可能会返回读/写文件描述符。

模式提供以下符号常量:

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其他人有执行权限

模式必须在O_CREAT位于标志中时指定,否则将被忽略。

creat等同于使用等于O_CREAT | O_WRONLY | O_TRUNC的 标志 打开

返回值

opencreat返回新的文件描述符,如果发生错误,则返回-1(在这种情况下,适当地设置errno )。 请注意, open可以打开设备专用文件,但creat不能创建它们 - 请改用mknod (2)。

在启用了UID映射的NFS文件系统上, open可能会返回一个文件描述符,但例如read (2)请求会被EACCES拒绝。 这是因为客户端通过检查权限来执行打开操作,但UID映射是由服务器在读取和写入请求时执行的。

如果该文件是新创建的,则其atime,ctime,mtime字段将设置为当前时间,父目录的ctime和mtime字段也将设置为当前时间。 否则,如果文件由于O_TRUNC标志而被修改,则它的ctime和mtime字段被设置为当前时间。

错误

EEXIST

路径名已经存在,并且使用了O_CREATO_EXCL

EISDIR

路径名指的是一个目录,并且所请求的访问涉及写入(即设置了O_WRONLYO_RDWR )。

EACCES

不允许请求访问该文件,或路径名中的某个目录不允许搜索(执行)权限,或该文件尚不存在,并且不允许对父目录执行写入访问。

ENAMETOOLONG

路径名太长。

ENOENT

O_CREAT未设置,并且指定的文件不存在。 或者, 路径名中的目录组件不存在,或者是悬挂的符号链接。

ENOTDIR

用作路径名中目录的组件实际上不是目录,或者指定了O_DIRECTORY ,而路径名不是目录。

ENXIO

O_NONBLOCK | O_WRONLY被设置,指定的文件是一个FIFO并且没有进程打开文件读取。 或者,该文件是设备专用文件,并且不存在相应的设备。

ENODEV

路径名是指设备专用文件,不存在相应的设备。 (这是一个Linux内核错误 - 在这种情况下,必须返回ENXIO。)

EROFS

路径名是指只读文件系统上的一个文件,并要求写访问。

ETXTBSY

路径名是指当前正在执行的可执行映像,并请求写入访问权限。

EFAULT

您可访问的地址空间之外的路径名点。

ELOOP

在解析路径名时遇到过多符号链接,或者指定了O_NOFOLLOW ,但路径名是符号链接。

ENOSPC

路径名被创建,但包含路径名的设备没有空间存放新文件。

ENOMEM

内核内存不足可用。

EMFILE

该过程已经打开了最大数量的文件。

ENFILE

系统上打开的文件总数已达到限制。

符合

SVr4,SVID,POSIX,X / OPEN,BSD 4.3 O_NOFOLLOWO_DIRECTORY标志是特定于Linux的标志。 可能需要定义_GNU_SOURCE宏来获取它们的定义。

限制

基于NFS的协议有许多不足之处,其中包括O_SYNCO_NDELAY

POSIX提供了三种不同的同步I / O变量,对应于标志O_SYNCO_DSYNCO_RSYNC 。 目前(2.1.130)这些在Linux下都是同义词。