Что я могу сделать, если getcwd () и getenv ("PWD") не совпадают? - PullRequest
4 голосов
/ 17 июля 2010

У меня есть инструмент системы сборки, который использует getcwd() для получения текущего рабочего каталога. Это здорово, за исключением того, что иногда у людей есть пробелы на пути, что не поддерживается системой сборки. Вы бы подумали, что можете просто сделать символическую ссылку:

ln -s "Directory With Spaces" DirectoryWithoutSpaces

А потом будь счастлив. Но, к сожалению для меня, getcwd() разрешает все символические ссылки. Я пытался использовать getenv("PWD"), но он не указывает на тот же путь, который я получаю от getcwd(). Я обвиняю make -C в том, что я не обновляю переменную среды. Прямо сейчас getcwd() возвращает мне путь, подобный этому:

/Users/carl/Directory With Spaces/Some/Other/Directories

И getenv("PWD") дает мне:

/Users/carl/DirectoryWithoutSpaces

Итак, есть ли какая-либо функция, подобная getcwd(), которая не разрешает символические ссылки?

Edit:

я изменил

make -C Some/Other/Directories

до

cd Some/Other/Directories ; make

А потом getenv("PWD") работает .. Если нет другого решения, я могу это использовать.

Ответы [ 2 ]

6 голосов
/ 17 июля 2010

В соответствии с Библией Стивенса «Расширенное программирование в среде UNIX», стр.112:

Поскольку ядро ​​должно сохранять знания о текущем рабочем каталоге, мы должны иметь возможность получить его текущее значение,К сожалению, для каждого процесса все ядро ​​поддерживает номер i-узла и идентификатор устройства для текущего рабочего каталога.Ядро не поддерживает полный путь к каталогу.

Извините, похоже, вам нужно обойти это другим способом.

3 голосов
/ 17 июля 2010

У getcwd() нет способа определить путь, по которому вы шли по символическим ссылкам.Базовая реализация getcwd() регистрирует текущий каталог '.', а затем открывает родительский каталог '..' и просматривает записи, пока не найдет имя каталога с тем же номером инода, что и у '.',Затем он повторяет процесс вверх, пока не найдет корневой каталог, после чего у него будет полный путь.Ни при каких условиях он никогда не пересекает символическую ссылку.Таким образом, цель getcwd() вычислить путь, по которому идут символические ссылки, невозможна, независимо от того, реализован ли он как системный вызов или как библиотечная функция.

Лучшее решение - убедиться, что система сборки обрабатывает имена путейсодержащие пробелы.Это означает цитирование путей, пропущенных через оболочку.Программы на C не заботятся о пробелах в имени;это только тогда, когда такая программа, как оболочка, интерпретирует строки, с которыми вы сталкиваетесь.(Компиляторы, реализованные в виде сценариев оболочки, которые запускают препроцессоры, часто имеют проблемы с путевыми именами, которые содержат пробелы - исходя из опыта.)

...