Реализация команды cd (cd -L) на C без функций exec

Я пытаюсь закодировать команду cd в C без использования функций exec, я уже сделал версию cd -P, но я не могу найти способ сделать cd (cd -L), потому что функция chdir разрешает символические ссылки поэтому мой cd -L действует как cd -P.

Для cd -P я сделал одну функцию, которая принимает путь, который мы хотим получить, в качестве параметра, и у меня есть переменная old_pwd, которая действует как $OLDPWD в моем файле (я использую getenv("PWD") для ее инициализации), если параметр пусто, я просто использую chdir для $HOME, если параметр "-", я использую chdir для переменной old_pwd и, наконец, если это путь, я использую chdir для этого пути. Если у вас есть идея, как изменить текущий каталог, не разрешая символическую ссылку, я буду очень признателен!

cd не может быть реализован как программа, только как команда в какой-либо другой программе (например, в оболочке). Какой здесь контекст?
Davis Herring 20.11.2022 22:16

@DavisHerring, я считаю, что ОП говорит о реализации cd в контексте пользовательской оболочки. Тем не менее, POSIX требует, чтобы cd, как стандартная утилита, а не «специальная встроенная», была доступна в виде команды, к которой можно получить доступ через семейство функций exec. Интересно, однако, что хотя и моя рабочая станция Linux, и мой Mac действительно предоставляют такую ​​внешнюю команду cd, их /bin/cd и /usr/bin/cd соответственно не обеспечивают поведения, соответствующего спецификациям POSIX.

John Bollinger 21.11.2022 20:10

Я пытаюсь сделать свою собственную оболочку на C, я делаю разные файлы для команд, которые хочу реализовать, и сейчас я сосредоточен на cd, используя chdir. Проблема, которую я пытался объяснить, заключается в том, что я не хочу следовать какой-либо символической ссылке в пути, но, поскольку chdir разрешает их, я не могу найти решение. Я пытался понять алгоритм, данный @JohnBollinger, но я не уверен, что действительно понял его, и если пример, который я привел ниже, был неправильным.

Chae 21.11.2022 20:43

@JohnBollinger: Интересно: в некоторых из моих систем нет cd на PATH, а в тех, которые есть, он есть в виде сценария оболочки! Я также не вижу требования, чтобы это была программа. В любом случае, вы были правы насчет контекста.

Davis Herring 21.11.2022 22:57

@DavisHerring, общим требованием ко всем стандартным утилитам POSIX (которые есть cd), кроме специальных встроенных утилит (которые нет cd), является то, что они должны быть доступны в форме, которую можно использовать с помощью семейства exec функций. Это находится в разделе 1.6 главы «Оболочка и утилиты» POSIX.

John Bollinger 22.11.2022 00:00
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
1
5
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

POSIX Разрешение пути работает с путем поэтапно, от начала до конца, разрешая символические ссылки по мере их прохождения. Вот как POSIX chdir() интерпретирует пути, и это согласуется с поведением cd -P.

Cd -L требует другого поведения: чтобы шаги формы .. интерпретировались относительно других буквальных шагов в данном пути, независимо от того, обозначают ли какие-либо шаги символические ссылки. Это поведение отличается от поведения chdir(), поэтому вам придется реализовать его самостоятельно. В основном это вопрос разбора и обработки появления . и .. в пути перед передачей результата chdir().

Спецификации POSIX для cd, указанные выше, предоставляют подробный алгоритм того, как cd -L должен выполнять необходимые манипуляции с путями. Таким образом, я удалил алгоритм, представленный в более ранней версии этого ответа, и заменил примечания, касающиеся его, примечаниями, относящимися к официальным спецификациям POSIX.

Заметки:

  1. POSIX определяет неясную переменную среды CDPATH и некоторую семантику поиска в каталогах для cd, связанную с ней. Подробности в связанных спецификациях. Если вы собираетесь использовать полную семантику POSIX, вам нужно будет справиться с этим; в противном случае я сомневаюсь, что очень многие люди заметят отсутствие этой функции.

  2. Эффект -P заключается в передаче указанного пути в chdir() как есть, при условии, что фактически указан любой целевой путь, или в передаче значения $HOME в chdir(), если путь не указан иначе.

  3. Когда действует -L, относительные пути интерпретируются относительно текущего значения $PWD. Это учитывается при обработке ведущих .. шагов пути.

  4. POSIX указывает, что обработка .. приводит к сбою cd с ошибкой, если ведущий путь, предшествующий .., интерпретируемый в соответствии со стандартным правилом разрешения пути (включая обход символической ссылки), не обозначает каталог. То есть,

    • Dir1/dir2/.. и dir1/symlink-to-dir3/.. оба допустимы, и оба эквивалентны dir1, но

    • Dir1/regular-file/.., dir1/not-a-filename/.. и подобные ошибочны.

  5. Поведение -L используется по умолчанию, если не указано ни -P, ни -L.

Привет, спасибо за ваш ответ, я просто хотел получить некоторые разъяснения: если у меня есть такие каталоги: test/dir1/dir2/dir3 и test/dir4 с test/dir4 -> test/dir1/dir2/dir3 символической ссылкой, если я нахожусь в dir4 и хочу добраться до test, а не dir2, используя cd .. путь не изменится с алгоритмом, который вы дали, но если я использую chdir на .., он все равно приведет меня к dir2, а не test, потому что он будет следовать символической ссылке в dir4 Так должен ли .. измениться с этим алгоритмом?

Chae 21.11.2022 19:26

@Chae, я серьезно пересмотрел этот ответ. Теперь он отсылает вас к официальным спецификациям POSIX для cd, которые включают собственный алгоритм того, как cd -L должен изменять пути. При этом учитывается представление оболочки о пути к текущему рабочему каталогу (из $PWD), когда -P не действует.

John Bollinger 21.11.2022 20:50

Другие вопросы по теме