为什么 realpath() return 错误 EEXIST?

Why does realpath() return error EEXIST?

我的程序是运行在Linux环境下,用gcc 4.4.7版编译。

我正在使用 realpath() 到 "canonicalize" 文件路径。我给realpath()的每个目录和文件的路径肯定存在,这当然是realpath()正常工作所必需的。

但是,有时 realpath() 会失败,错误代码为 17,名称 EEXIST,字符串描述 "File exists"。

这让我很困惑。当然存在,我尖叫着 realpath()。但是realpath()对我的咆哮不为所动

http://pubs.opengroup.org/onlinepubs/009695399/functions/realpath.htmlrealpath() 文档列出了导致其失败的错误,但 EEXIST 不是其中之一。

为什么realpath()会这样失败?

导致 EEXIST 错误的目录和文件路径示例:

但这些示例不是确定的,因为具有完全相同模式且位于相同目录中的其他文件也会成功。

对于哪个目录或文件会导致 EEXIST 错误似乎没有任何韵律或原因。该错误通常只发生在我尝试规范化的第一个文件路径上,而不会发生在后续文件路径上。但是,我不能仅仅通过尝试再次规范化第一个文件来绕过它;错误将继续发生。

程序片段:

#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>    // for PATH_MAX

using std;

string PathCanonicalize( string const & path )
{
  string result;

  char szResult[ PATH_MAX ];
  ::realpath( path.c_str(), szResult );
  if ( errno == EEXIST )
  {
    // Why?
    cerr << "realpath: error code " << errno << ", " << ::strerror( errno ) << ": '" << path << "'.  Of course the file exists!" << endl;

    result = path;
  }
  else if ( errno )
  {
    cerr << "realpath: error code " << errno << ", " << ::strerror( errno ) << ": '" << path << "'" << endl;

    result = path;
  }
  else
  {
    result = szResult;
  }

  return result;      
}

如果没有特定原因,您永远不应该检查 errno

也许 realpath 发生的任何内部操作最后都失败了 EEXIST。或者可能 errno 恰好是 EEXIST 来自之前的一些失败的操作并且 realpath 没有改变它。

如果这不会导致 realpath 失败,您为什么要关心?

来自你自己的 link:

Upon successful completion, realpath() shall return a pointer to the resolved name. Otherwise, realpath() shall return a null pointer and set errno to indicate the error, and the contents of the buffer pointed to by resolved_name are undefined.

请注意,如果 realpath 成功,它并没有说 errno 被设置为任何特定值。那么,为什么在检查 realpath 是否成功之前先检查 errno

也就是说,您不应该通过检查 'errno' 值来认为 realpath() 是 failed/succeeded,您应该根据 NULL 检查它的返回值。如果返回 NULL,那么您可以检查 'errno' 以找出根本原因。 换句话说,如果 realpath() 成功,它可能不会 change/reset/clear 'errno' 值 - 为它分配 0。只有失败时,才会设置'errno'作为错误码。