Почему getcwd не работает с ошибкой ENOENT

Я использую getcwd функция для получения текущего рабочего каталога моего приложения.
В некоторых случаях это терпит неудачу, и errno является ENOENT. Я вызываю getcwd из разных потоков, но поочередно, а иногда сталкиваюсь с ENOENT, но не знаю почему.
Ссылка выше говорит о том, что ENOENT означает, что «текущий рабочий каталог был не связан». но каталог существует.

Вот фрагмент функции, которую я использую:

ОБНОВЛЕНИЕ: Код обновлен советом от @Aganju и @molbdnilo:

std::string get_working_dir()
{
char buf[PATH_MAX];
memset(buf, 0, sizeof(buf));
char * result = getcwd(buf, sizeof(buf));
std::string working_path = buf;
// Check for possible errors.
if (result == NULL)
{
switch (errno)
{
case EACCES:
break;
case EFAULT:
break;
case EINVAL:
break;
case ENAMETOOLONG:
break;
case ENOENT:
{
if (working_path.empty())
{
const char* pwd = getenv("PWD");
working_path = (pwd) ? pwd : "";
}
break;
}
case ERANGE:
break;
default:
break;
}
return working_path;
}
}

В случае, если я сталкиваюсь с ENOENT, я получаю переменную окружения «PWD», потому что я работаю на CentOS 5.11 и Ubuntu 16.04, а когда getcwd дает сбой в CentOS, он возвращает пустой буфер.

ОБНОВИТЬ:

Я заметил, что вызов из основного потока не завершается ошибкой, но когда я вызываю функцию из другого потока, она завершается неудачно, и errno является ENOENT.

0

Решение

Как molbdnilo сказал, что вы должны проверить возвращаемое значение в первую очередь.

В руководстве вы ссылаетесь на штаты:

[…] При сбое эти функции возвращают NULL, а errno устанавливается в
указать ошибку. […]

Другими словами, если есть нет недостаточность, errno является не установить, и содержит все, что он содержал от любого вызова, случившегося раньше, может быть, задолго до этого, что не имеет смысла в этом контексте.

Используйте что-то вроде char * result = getcwd(buf, sizeof(buf));, а затем проверьте if (result == NULL) { switch (errno) ..., так далее.

2

Другие решения

Это может произойти в следующей ситуации, которую мы можем проиллюстрировать на диаграмме последовательности из нескольких процессов, используя синтаксис сценария оболочки:

process A                     process B
$ cd ~                        $ cd ~
user $ mkdir foo
user $ cd foo
user $ rm -rf foo
user/foo $ pwd
/home/user/foo
user/foo $ cd .
cd: error retrieving current
directory: getcwd: cannot access
parent directories: No such file or directory

Каждый процесс в Unix-подобной операционной системе имеет текущий рабочий каталог, который содержит ссылку на объект в файловой системе. Этот объект не может быть возвращен как свободное место, пока процесс не удалит этот текущий каталог.

Выше процесс А продолжает удерживать каталог, который раньше был ~/foo, Тот дорожка больше не существует в структуре каталогов, но каталог объект продолжает существовать.

getcwd Системный вызов понимает это: он видит, что текущий рабочий каталог вызывающего процесса не связан с структурой каталогов и, следовательно, не имеет пути, поэтому он сообщает об ошибке.

pwd Команда оболочки работает, потому что она просто извергает часть данных, о которой оболочка знает без вызова getcwd; но когда мы пытаемся cd .возникает ошибка (воспроизводится с помощью Bash в системе GNU / Linux; результаты могут отличаться).

1

По вопросам рекламы [email protected]