3

我的程序在 Linux 环境中运行,使用 gcc 版本 4.4.7 编译。

我正在使用realpath()“规范化”文件路径。我提供的每个目录和文件的路径肯定存在,这对于正常工作realpath()当然是必不可少的。realpath()

但是,有时realpath()会失败,错误代码为 17,名称EEXIST,字符串描述“文件存在”。

这让我很困惑。它当然存在,我尖叫着realpath()。但realpath()对我的咆哮无动于衷。

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

为什么realpath()会以这种方式失败?

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

  • 目录的绝对路径: /alpha/bravo/charlie/delta
  • 文件的绝对路径: /alpha/bravo/charlie/foo.txt
  • 文件的相对路径: ../../charlie/foo.txt
  • 包含一个额外点的文件的路径: /alpha/bravo/Charlie/./foo.txt

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

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;      
}
4

2 回答 2

7

您永远不应该在没有errno特定原因的情况下进行检查。

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

如果这没有导致realpath失败,你为什么在乎?

从您自己的链接:

成功完成后,realpath() 将返回一个指向解析名称的指针。否则,realpath() 将返回一个空指针并设置 errno 以指示错误,且已解析名称指向的缓冲区内容未定义。

请注意,如果成功,它并没有errno特别设置为任何内容。realpath那么为什么要errno在检查是否realpath成功之前检查呢?

于 2015-06-04T17:21:30.900 回答
-1

也就是说,您不应该通过检查“errno”值来认为 realpath() 失败/成功,您应该根据 NULL 检查其返回值。如果返回 NULL,那么您可以检查 'errno' 以找出根本原因。换句话说,如果 realpath() 成功,它可能不会更改/重置/清除 'errno' 值 - 为其分配 0。只有在失败时,它才会将'errno'设置为错误代码。

于 2019-12-26T03:17:34.593 回答