• FTW_STOP — не обрабатывать дальнейшие записи в дереве каталога, как при обычном ненулевом результате функции func(). Процессу, который вызывал функцию nftw(), возвращается значение FTW_STOP.

Можно указать проверочное макроопределение _GNU_SOURCE, чтобы получить определение FTW_ACTIONRETVAL из файла .

18.10. Текущий рабочий каталог процесса

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

Извлечение имени текущего рабочего каталога

Процесс может извлечь имя своего текущего рабочего каталога с помощью функции getcwd().

#include

char *getcwd(char *cwdbuf, size_t size);

Возвращает значение cwdbuf при успешном завершении или NULL при ошибке

Функция getcwd() помещает строку с завершающим нулем, содержащую абсолютное имя пути для текущего рабочего каталога, в выделенный буфер, на который указывает аргумент cwdbuf. Вызывающий процесс должен выделить буфер cwdbuf размером по меньшей мере size байт. (Обычно размер этого буфера задается с помощью константы PATH_MAX.)

При успешном завершении функция getcwd() возвращает указатель на cwdbuf в качестве результата работы функции. Если имя пути текущего рабочего каталога превышает величину size байт, функция getcwd() возвращает NULL, а переменной errno присваивается значение ERANGE.

В Linux/x86-32 функция getcwd() возвращает максимум 4096 (PATH_MAX) байт. Если длина имени текущего рабочего каталога (а также буфер cwdbuf и значение size) превышает данный предел, имя пути обрезается без уведомления об этом, в результате чего удаляются полные префиксы каталогов от начала строки (которая по-прежнему завершается нулем). Иными словами, мы не можем с уверенностью использовать функцию getcwd(), когда длина абсолютного имени пути для текущего рабочего каталога превышает данный предел.

По сути, функция getcwd() в Linux внутренним образом выделяет страницу виртуальной памяти для возвращаемого имени пути. В архитектуре x86-32 размер такой страницы равен 4096 байтам, однако в архитектурах с большим размером страниц (например, в архитектуре Alpha с размером страницы 8192 байта) возможен возврат более длинных имен путей.

Если буфер cwdbuf равен NULL, а размер size нулевой, то оберточная функция для функции getcwd() из библиотеки glibc выделяет буфер необходимого размера и возвращает указатель на этот буфер в качестве результата функции. Чтобы избежать утечек памяти, вызывающий процесс должен впоследствии освободить данный буфер с помощью функции free(). В портируемых приложениях не следует полагаться на ее надежность. В большинстве других реализаций предложено более простое расширение спецификации стандарта SUSv3: если буфер cwdbuf равен NULL, то функция getcwd() выделяет size байт и использует этот буфер для возврата результата вызывающему процессу. Реализация функции getcwd() в библиотеке glibc тоже обеспечивает такую особенность.

GNU-библиотека C предоставляет также еще две функции для получения имени текущего рабочего каталога. Заимствованная из BSD-версии функция getwd(path) подвержена переполнению буфера, поскольку она не предлагает способа указания верхнего предела на размер возвращаемого имени пути. Функция get_current_dir_name() возвращает строку, содержащую имя текущего рабочего каталога. Эту функцию легко использовать, но она не является портируемой. Из соображений безопасности и портируемости функция getcwd() предпочтительнее, чем две названные (если мы стремимся избежать применения расширений библиотеки GNU).

Имея подходящие права доступа (грубо говоря, если мы являемся владельцем процесса или обладаем возможностью CAP_SYS_PTRACE), можно определить имя текущего рабочего каталога для любого процесса, прочитав (readlink()) содержимое специфичной для Linux символической ссылки /proc/PID/cwd.

Изменение текущего рабочего каталога

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

#include

int chdir(const char *pathname);

Возвращает 0 при успешном завершении или –1 при ошибке

Системный вызов fchdir() выполняет то же, что и вызов chdir(), только каталог указывается с помощью файлового дескриптора, полученного ранее при открытии каталога, задействуя системный вызов open().

#define _XOPEN_SOURCE 500 /* Или: #define _BSD_SOURCE */

#include

int fchdir(int fd);

Возвращает 0 при успешном завершении или –1 при ошибке

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

int fd;

fd = open(".", O_RDONLY); /* Запоминаем, где мы находимся */

chdir(somepath); /* Переходим в другое место */

Перейти на страницу:

Похожие книги