Книга: Linux программирование в примерах
8.4.2. Получение текущего каталога: getcwd()
8.4.2. Получение текущего каталога: getcwd()
Названная должным образом функция getcwd()
получает абсолютный путь текущего рабочего каталога.
#include <unistd.h> /* POSIX */
char *getcwd(char *buf, size_t size);
Функция заносит в buf
путь; ожидается, что размер buf
равен size
байтам. При успешном завершении функция возвращает свой первый аргумент. В противном случае, если требуется более size
байтов, она возвращает NULL
и устанавливает в errno ЕRANGE
. Смысл в том, что если случится ERANGE
, следует попытаться выделить буфер большего размера (с помощью malloc()
или realloc()
) и попытаться снова.
Если любой из компонентов каталога, ведущих к текущему каталогу, не допускает чтения или поиска, getcwd()
может завершиться неудачей, а errno
будет установлен в EACCESS
. Следующая простая программа демонстрирует ее использование:
/* ch08-getcwd.c --- демонстрация getcwd().
Проверка ошибок для краткости опущена */
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void) {
char buf[PATH_MAX];
char *cp;
cp = getcwd(buf, sizeof(buf));
printf("Current dir: %sn", buf);
printf("Changing to ..n");
chdir(".."); /* 'cd ..' */
cp = getcwd(buf, sizeof(buf));
printf("Current dir is now: %sn", buf);
return 0;
}
Эта простая программа выводит текущий каталог, переходит в родительский каталог, затем выводит новый текущий каталог. (Переменная cp
здесь на самом деле не нужна, но в реальной программе она была бы использована для проверки ошибок). При запуске программа создает следующий вывод:
$ ch08-getcwd
Current dir: /home/arnold/work/prenhall/progex/code/ch08
Changing to ..
Current dir is now: /home/arnold/work/prenhall/progex/code
Формально, если аргумент buf
равен NULL
, поведение getcwd()
не определено. В данном случае версия GLIBC getcwd()
вызовет malloc()
за вас, выделяя буфер с размером size
. Идя даже дальше, если size
равен 0, выделяется «достаточно большой» буфер для вмещения возвращенного имени пути. В любом случае вы должны вызвать для возвращенного указателя free()
после завершения работы с буфером.
Поведение GLIBC полезно, но не переносимо. Для кода, который должен работать на разных платформах, вы можете написать замещающую функцию, которая предоставляет те же самые возможности, в то же время заставив ее непосредственно вызывать getcwd()
на системе с GLIBC.
Системы GNU/Linux предоставляют файл /proc/self/cwd
. Этот файл является символической ссылкой на текущий каталог:
$ cd /tmp /* Сменить каталог */
$ ls -l /рroc/self/cwd /* Посмотреть на файл */
lrwxrwxrwx 1 arnold devel 0 Sep 9 17:29 /proc/self/cwd -> /tmp
$ cd /* Перейти в домашний каталог */
$ ls -l /proc/self/cwd /* Снова посмотреть на него */
lrwxrwxrwx 1 arnold devel 0 Sep 9 17:30 /proc/self/cwd -> /home/arnold
Это удобно на уровне оболочки, но представляет проблему на уровне программирования. В частности, размер файла равен нулю! (Это потому, что это файл в /proc
, который продуцирует ядро; это не настоящий файл, находящийся на диске.)
Почему нулевой размер является проблемой? Если вы помните из раздела 5.4.5 «Работа с символическими ссылками», lstat()
для символической ссылки возвращает в поле st_size
структуры struct stat
число символов в имени связанного файла. Это число может затем использоваться для выделения буфера соответствующего размера для использования с readlink()
. Здесь это не будет работать, поскольку размер равен нулю. Вам придется использовать (или выделять) буфер, который, как вы полагаете, достаточно большой. Однако, поскольку readlink()
не выдает символов больше, чем вы предоставили места, невозможно сказать, достаточен буфер или нет; readlink()
не завершается неудачей, когда недостаточно места. (См. в разделе 5.4.5 «Работа с символическими ссылками» функцию Coreutils xreadlink()
, которая решает проблему.)
В дополнение к getcwd()
GLIBC имеет несколько других непереносимых процедур. Они избавляют вас от хлопот по управлению буферами и обеспечивают совместимость со старыми системами BSD. Подробности см в getcwd(3).
- Получение статистики
- Получение помощи
- Получение помощи по работе с книгой и компакт-диском
- Получение помощи по Windows SharePoint Services 3.0
- Получение доменного имени
- Можно ли указать использование по умолчанию вместо C:Program Files другого каталога для установки программ?
- У файла и каталога есть атрибуты (например: Скрытый, Только чтение). Как ими управлять из командной строки?
- 4.8. Получение прав root
- Получение страниц заполненных нулями
- Получение статистики браузера
- Удаление ключа из вашего каталога ключей.
- Получение, создание и отправка электронной корреспонденции