如果filepath存在,open(filepath,O_WRONLY | O_EXCL)是否返回值?

如果filepath存在,open(filepath,O_WRONLY | O_EXCL)是否返回值?,c,C,我知道如果filepath存在,openfilepath,O|u WRONLY | O|u EXCL将失败,但它会返回任何东西吗 现在,如果我想知道一个文件是否存在,如果它存在,我想打印一条消息,我应该在上面的open命令中包含O_EXCL标志吗 编辑:我想我犯了一个错误,我应该使用openfilepath,O_CREAT | O|u EXCLopenfilepath,O_WRONLY | O|u EXCL不会在文件路径存在时失败,如果文件路径不存在或您没有写访问权限时失败 O_EXCL只能与O

我知道如果filepath存在,openfilepath,O|u WRONLY | O|u EXCL将失败,但它会返回任何东西吗

现在,如果我想知道一个文件是否存在,如果它存在,我想打印一条消息,我应该在上面的open命令中包含O_EXCL标志吗

编辑:我想我犯了一个错误,我应该使用openfilepath,O_CREAT | O|u EXCL

openfilepath,O_WRONLY | O|u EXCL不会在文件路径存在时失败,如果文件路径不存在或您没有写访问权限时失败

O_EXCL只能与O_CREAT一起使用,然后必须传递一个额外的参数来指定要创建的文件的模式位:

int hd = open(filepath, O_WRONLY | O_CREAT | O_EXCL, 0644);
如果出现故障,hd将为负值,并且将设置errno以指示错误原因。使用perror报告故障并显示错误消息

您也可以使用access测试文件存在性和写访问权限,但这不适合您的用例,因为文件可能是通过access测试和打开调用之间的并发进程创建的。

openfilepath,O_WRONLY | O_EXCL不会在filepath存在时失败,如果它不存在或您没有写访问权限,它将失败

O_EXCL只能与O_CREAT一起使用,然后必须传递一个额外的参数来指定要创建的文件的模式位:

int hd = open(filepath, O_WRONLY | O_CREAT | O_EXCL, 0644);
如果出现故障,hd将为负值,并且将设置errno以指示错误原因。使用perror报告故障并显示错误消息


您也可以使用access测试文件存在性和写访问权限,但这不适合您的用例,因为文件可能是由access测试和打开调用之间的并发进程创建的。如果打开因任何原因失败,它将返回-1并设置errno以指示原因。详细信息在open2手册页面中。在任何Unixy系统中键入man 2 open。

如果open因任何原因失败,它将返回-1并设置errno以指示原因。详细信息在open2手册页面中。在任何Unixy系统中键入man 2 open。

以下是一个重要提示:

通常,如果使用O_EXCL,则其行为是未定义的 没有你的创造。有一个例外:在Linux 2.6和 稍后,如果引用路径名,则可以使用O_EXCL而无需O_CREAT 连接到块设备


因此,除非有一个用例,否则您的命令将调用未定义的行为。

来自

通常,如果使用O_EXCL,则其行为是未定义的 没有你的创造。有一个例外:在Linux 2.6和 稍后,如果引用路径名,则可以使用O_EXCL而无需O_CREAT 连接到块设备

因此,除非有一个用例,否则您的命令将调用未定义的行为。

来自open的手册页:

O_EXCL确保此调用创建文件:如果此标志为speci‐if 与O_CREAT一起验证,且路径名已存在, 然后open失败,错误为EEXIST

          When these two flags are specified, symbolic links are not  fol‐
          lowed: if pathname is a symbolic link, then open() fails regard‐
          less of where the symbolic link points.

          In general, the behavior of O_EXCL is undefined if  it  is  used
          without  O_CREAT.   There  is  one  exception:  on Linux 2.6 and
          later, O_EXCL can be used without O_CREAT if pathname refers  to
          a  block  device.   If  the block device is in use by the system
          (e.g., mounted), open() fails with the error EBUSY.
因此,如果文件已经存在,那么它将失败的前提是不完全正确的

但是,当它失败时:根据手册页

open(), openat(), and creat() return the new file descriptor, or -1  if
   an error occurred (in which case, errno is set appropriately).
从“打开”的手册页:

O_EXCL确保此调用创建文件:如果此标志为speci‐if 与O_CREAT一起验证,且路径名已存在, 然后open失败,错误为EEXIST

          When these two flags are specified, symbolic links are not  fol‐
          lowed: if pathname is a symbolic link, then open() fails regard‐
          less of where the symbolic link points.

          In general, the behavior of O_EXCL is undefined if  it  is  used
          without  O_CREAT.   There  is  one  exception:  on Linux 2.6 and
          later, O_EXCL can be used without O_CREAT if pathname refers  to
          a  block  device.   If  the block device is in use by the system
          (e.g., mounted), open() fails with the error EBUSY.
因此,如果文件已经存在,那么它将失败的前提是不完全正确的

但是,当它失败时:根据手册页

open(), openat(), and creat() return the new file descriptor, or -1  if
   an error occurred (in which case, errno is set appropriately).

谢谢你把事情弄清楚。那么,如果我尝试在已经存在的文件路径上使用openfilepath,O|u CREAT | O|u EXCL,它会因为错误而返回负值,这是真的吗。那么,如果我尝试在已经存在的文件路径上使用openfilepath,O|u CREAT | O|u EXCL,它会因为错误而返回负值,这是真的吗?请注意,access在这里或任何地方都不是一个好工具,因为它有TOCTOU问题,注意,access在这里或任何地方都不是一个好工具,因为1它有TOCTOU问题,2它使用真实uid/gid无效uid/gid.openfilepath,O_CREAT | O_EXCL也不正确:它应该是openfilepath,O|WRONLY | O| u CREAT | O| u EXCL,0644openfilepath,O|u CREAT | O|u EXCL也不正确:它应该是openfilepath,O|u WRONLY | O|u CREAT | O|u EXCL,0644