Скачиваний:
84
Добавлен:
12.05.2015
Размер:
533.5 Кб
Скачать

4.22. Функции chdir, fchdir, getcwd и chroot

У каждого процесса есть свой текущий рабочий каталог. Относительно этого каталога вычисляются все относительные пути к файлам. Когда пользователь входит в систему, текущим рабочим каталогом обычно становится каталог, указанный в шестом поле записи из файла /etc/passwd, – домашний каталог пользователя. Текущий рабочий каталог – это атрибут процесса, домашний каталог – атрибут пользователя.

Процесс может изменить текущий рабочий каталог с помощью функций chdir и fchdir.

#include <unistd.h>

int chdir (const char *pathname);

int fchdir (int filedes);

/* обе функции возвращают 0 в случае успеха, -1 – в случае ошибки */

Новый рабочий каталог может быть задан строкой pathname или файловым дескриптором filedes.

Пример. Поскольку текущий рабочий каталог является атрибутом процесса, то вызов функцииchdirв дочернем процессе никак не влияет на текущий рабочий каталог родительского процесса.

Листинг 4.8. Пример использования функции chdir

#include <errno.h>

#include <stdio.h>

int main(void)

{

if (chdir("/tmp") < 0)

{

fprintf(stderr, "Ошибка вызова функции chdir: %s\n", strerror(errno));

exit(1);

}

printf("Каталог /tmp стал текущим рабочим каталогом\n");

exit(0);

}

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

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

Чтобы определить абсолютный путь к текущему рабочему каталогу, нужна функция, которая будет перемещаться вверх по дереву каталогов, начиная с текущего каталога (точка “.”), и далее переходя в каталоги с именами две точки “..”, пока не будет достигнут корневой каталог. В каждом из промежуточных каталогов функция будет читать записи из каталога, пока не найдет название, которое соответствует индексному узлу предыдущего каталога. К счастью, такая функция уже существует.

#include <unistd.h>

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

/* возвращает непустой указатель на buf в случае успеха, NULL – в случае ошибки */

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

Функция getcwdочень удобна для приложений, в которых возникает необходимость возврата к первоначальному рабочему каталогу. Для этого перед сменой текущего рабочего каталога нужно вызватьgetcwdи сохранить полученное значение. По окончании работы следует передать сохраненное значение функцииchdirи вернуться в первоначальный рабочий каталог.

Функция fchdirпредоставляет еще более простой способ решения этой задачи. Вместо вызова функцииgetcwdможно открыть текущий каталог с помощью функцииopen, разумеется, в режиме только для чтения, сохранить файловый дескриптор и после этого сменить текущий каталог. Когда возникнет необходимость вернуться к первоначальному местоположению, остается просто передать сохраненный дескриптор функцииfchdir.

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

#include <unistd.h>

int chroot(const char *path);

/* функция возвращает 0 в случае успеха, -1 – в случае ошибки */

Аргумент pathname– это имя каталога, который впоследствии будет рассматриваться ядром в качестве корневого каталога для процесса.

Индексный узел нового корневого каталога становится логическим корнем файловой системы для процесса и для всех порожденных им процессов. Это означает, что все пути поиска, начинающиеся с корня "/", возьмут начало с данного индексного узла и что все попытки войти в каталог ".." над корнем приведут к тому, что рабочим каталогом процесса останется новый корневой каталог. Процесс передает всем вновь порождаемым процессам этот каталог в качестве корневого подобно тому, как передает свой текущий каталог. Правом изменения корневого каталога обладает только суперпользователь.

Соседние файлы в папке Chapter.2