Моя программа работает в среде Linux, скомпилированной с gcc версии 4.4.7.
я использую realpath()
«канонизировать» пути к файлам. Путь к каждому каталогу и файлу, который я передаю realpath()
безусловно, существует, что, конечно, важно для realpath()
работать правильно.
Однако иногда realpath()
не удастся с кодом ошибки 17, имя EEXIST
, описание строки «Файл существует».
Это сбивает меня с толку. Конечно, существует, я кричу на realpath()
, Но realpath()
не тронут моим разглагольствованием.
Документация для realpath()
в http://pubs.opengroup.org/onlinepubs/009695399/functions/realpath.html перечисляет ошибки, которые вызывают его сбой, но 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;
}
Вы никогда не должны проверять errno
без конкретной причины.
Возможно, какая-то внутренняя операция realpath
случилось в последний раз не удалось с EEXIST
, Или, может быть errno
случилось быть EEXIST
от какой-то предыдущей операции, которая потерпела неудачу и realpath
не изменил это.
Если это не вызвало realpath
потерпеть неудачу, почему тебя это волнует?
По вашей собственной ссылке:
После успешного завершения realpath () возвращает указатель на разрешенное имя. Иначе, realpath () должен вернуть нулевой указатель и установить errno для указания ошибки, а содержимое буфера, на которое указывает resolved_name, не определено.
Обратите внимание, это не говорит, что errno
установлен на что-нибудь, в частности, если realpath
преуспевает. Так почему ты проверяешь errno
перед проверкой, если realpath
удалось?