Литмир - Электронная Библиотека
A
A

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 заканчивает работу, закрывая открытый дескриптор файла. Вот что происходит при запуске программы.

$ <b>ls -ld .</b> /* Показать текущие права доступа */

drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 .

$ <b>ch08-chdir</b> /* Запустить программу */

fchdir back: Permission denied /* Ожидаемая неудача */

$ <b>ls -ld .</b> /* Снова посмотреть на права доступа */

drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 /* Все восстановлено как раньше */

8.4.2. Получение текущего каталога:

getcwd()

Названная должным образом функция

getcwd()
получает абсолютный путь текущего рабочего каталога.

#include &lt;unistd.h&gt; /* 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 &lt;stdio.h&gt;

#include &lt;fcntl.h&gt;

#include &lt;unistd.h&gt;

#include &lt;sys/types.h&gt;

#include &lt;sys/stat.h&gt;

int main(void) {

 char buf[PATH_MAX];

 char *cp;

 cp = getcwd(buf, sizeof(buf));

 printf(&quot;Current dir: %s\n&quot;, buf);

 printf(&quot;Changing to ..\n&quot;);

 chdir(&quot;..&quot;); /* 'cd ..' */

 cp = getcwd(buf, sizeof(buf));

 printf(&quot;Current dir is now: %s\n&quot;, buf);

вернуться

83

На системах GNU/Linux и BSD для получения нижележащего дескриптора файла можно применить функцию

dirfd()
к указателю
DIR*
, см. справочную страницу GNU/Linux dirfd(3) — Примеч. автора.

101
{"b":"576259","o":1}