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;
}
source to share
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
?
source to share