Книга: Linux программирование в примерах

8.4.1. Смена каталога: chdir() и fchdir()

8.4.1. Смена каталога: chdir() и fchdir()

В разделе 1.2 «Модель процессов Linux/Unix» мы говорили:

Текущим каталогом является каталог, относительно которого отсчитываются относительные пути (те, которые не начинаются с /). Это каталог, «в» котором вы находитесь, когда даете оболочке команду 'cd некоторое_место'.

У каждого процесса есть текущий рабочий каталог. Каждый новый процесс наследует свой текущий каталог от процесса, который его запустил (своего родителя). Две функции позволяют перейти в другой каталог:

#include <unistd.h>
int chdir(const char *path); /* POSIX */
int fchdir(int fd); /* XSI */

Функция chdir() принимает строку с названием каталога, тогда как fchdir() ожидает дескриптор файла, который был открыт для каталога с помощью open().[83] Обе возвращают 0 при успехе и -1 при ошибке (с errno, установленной соответствующим образом). Обычно, если open() для каталога завершается успешно, fchdir() также достигает цели, если кто-то не изменил права доступа к каталогу между вызовами, (fchdir() сравнительно новая функция; на старых системах Unix ее нет.)

Использование этих функций почти тривиально. Следующая программа, ch08-chdir.c, демонстрирует обе функции. Она демонстрирует также, что fchdir() может потерпеть неудачу, если права доступа открытого каталога не включают доступа на поиск (исполнение).

1  /* ch08-chdir.c --- демонстрация chdir() и fchdir().
2     Для краткости проверка ошибок опущена */
3
4  #include <stdio.h>
5  #include <fcntl.h>
6  #include <unistd.h>
7  #include <sys/types.h>
8  #include <sys/stat.h>
9
10 int main(void)
11 {
12  int fd;
13  struct stat sbuf;
14
15  fd = open(".", O_RDONLY); /* открыть каталог для чтения */
16  fstat(fd, &sbuf); /* получить сведения, нужны начальные права доступа */
17  chdir(".."); /* 'cd ..' */
18  fchmod(fd, 0); /* отменить права доступа каталога */
19
20  if (fchdir(fd) < 0) /* попытаться выполнить 'cd' обратно, должно завершиться неудачей */
21   perror("fchdxr back");
22
23  fchmod(fd, sbuf.st_mode & 07777); /* восстановить первоначальные права доступа */
24  close(fd); /* все сделано */
25
26  return 0;
27 }

Строка 15 открывает текущий каталог. Строка 16 вызывает fstat() для открытого каталога, так что мы получаем копию его прав доступа. Строка 17 использует chdir() для перемещения на один уровень в иерархии файлов. Строка 18 выполняет грязную работу, отменяя все права доступа первоначального каталога.

Строки 20–21 пытаются перейти обратно в первоначальный каталог. Ожидается, что эта попытка будет безуспешной, поскольку текущие права доступа не позволяют это. Строка 23 восстанавливает первоначальные права доступа, 'sbuf.st_mode & 07777' получает младшие 12 битов прав доступа; это обычные 9 битов rwxrwxrwx и биты setuid, setgid и «липкий» бит, которые мы обсудим в главе 11 «Права доступа и ID пользователя и группы». Наконец, строка 24 заканчивает работу, закрывая открытый дескриптор файла. Вот что происходит при запуске программы.

$ ls -ld . /* Показать текущие права доступа */
drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 .
$ ch08-chdir /* Запустить программу */
fchdir back: Permission denied /* Ожидаемая неудача */
$ ls -ld . /* Снова посмотреть на права доступа */
drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 /* Все восстановлено как раньше */

Оглавление книги


Генерация: 1.198. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз