является непрозрачным типом. Код прост; строка 145 использует
type2str
для вывода типа файловой системы. Как для сходной программы, использующей
statvfs
, эта функция игнорирует файловые системы, которые не расположены на локальных устройствах (строки 133–134). Вот вывод на нашей системе:
$ ch08-statfs /* Запуск программы */
/, mounted on /dev/hda2: /* Результаты для файловой
системы ext2 */
f_type: ЕХТ2
f_bsize: 4096
f_blocks: 1549609
f_bfrее: 316664
f_bavail: 237946
f_files: 788704
f_ffree: 555483
f_namelen: 255
...
/win, mounted on /dev/hda1: /* Результаты для файловой с-мы vfat */
f_type: MSDOS
f_bsize: 4096
f_blocks: 2092383
f_bfree: 1391952
f_bavail: 1391952
f_files: 0
f_ffree: 0
f_namelen: 260
В заключение, использование
statvfs
или
statfs
в вашем собственном коде зависит от ваших потребностей. Как описано в предыдущем разделе, GNU
df
не использует
statvfs
под GNU/Linux и в общем имеет тенденцию использовать уникальный для каждой Unix-системы системный вызов «получения сведений о файловой системе». Хотя это работает, это не очень привлекательно. С другой стороны, иногда у вас нет выбора: например, проблемы GLIBC, о которых мы упоминали выше. В этом случае нет безупречного решения.
8.4. Перемещение по иерархии файлов
Несколько системных вызовов и стандартных библиотечных функций дают возможность изменять текущий каталог и определять полный путь к текущему каталогу. Более сложные функции позволяют осуществлять произвольные действия с каждым объектом файловой системы в иерархии каталогов.
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 ее нет.)
83
На системах GNU/Linux и BSD для получения нижележащего дескриптора файла можно применить функцию
dirfd
к указателю
DIR*
, см. справочную страницу GNU/Linux dirfd(3) — Примеч. автора.
Использование этих функций почти тривиально. Следующая программа,
ch08-chdir.c
, демонстрирует обе функции. Она демонстрирует также, что
fchdir
может потерпеть неудачу, если права доступа открытого каталога не включают доступа на поиск (исполнение).
1 /* ch08-chdir.c --- демонстрация chdir и fchdir.
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 заканчивает работу, закрывая открытый дескриптор файла. Вот что происходит при запуске программы.