Why does realpath () return EEXIST error?

My program runs in a Linux environment compiled with gcc version 4.4.7.

I use realpath()

to "canonicalize" file paths. The path of every directory and file I pass before realpath()

definitely exists, which is certainly necessary for it to work properly realpath()

.

However, sometimes it realpath()

is issued with an error code 17, name EEXIST

, string description "File exists".

This puzzles me. Of course it exists, I shout at realpath()

. But realpath()

not touched by my rant.

The documentation for realpath()

at http://pubs.opengroup.org/onlinepubs/009695399/functions/realpath.html lists errors that cause the crash, but is EEXIST

not one of them.

Why realpath()

doesn't it work this way?

Examples of directory and file paths that cause the error EEXIST

:

  • Absolute directory path: /alpha/bravo/charlie/delta

  • Absolute file path: /alpha/bravo/charlie/foo.txt

  • File relative path: ../../charlie/foo.txt

  • The path to the file with an additional dot in it: /alpha/bravo/Charlie/./foo.txt

But these examples are not final, because other files with the same templates and in the same directories will be fine.

There doesn't seem to be any rhyme or reason as to which directory or file will cause the error EEXIST

. The error usually only occurs for the first path to the file that I am trying to canonicalize, and then not for the subsequent ones. However, I can't fool him, just trying to canonicalize that first file again; the error will continue just for this.

Program snippet:

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

      

+3


source to share


1 answer


You should never check for errno

no particular reason.

Perhaps any internal operation realpath

happened with the last failed s EEXIST

. Or maybe it errno

ended up EEXIST

from a previous failed operation rather realpath

than changing it.

If it didn't cause an error realpath

, why do you care?



From your own link:

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

Note that it does not say that it is errno

set on anything, in particular if it realpath

succeeds. So why are you checking errno

before checking if it succeeded realpath

?

+4


source







All Articles