146 printf("\tf_bsize: %ld\n", vfs.f_bsize);
147 printf("\tf_blocks: %ld\n", vfs.f_blocks);
148 printf("\tf_bfree: %ld\n", vfs.f_bfree);
149 printf("\tf_bavail: %ld\n", vfs.f_bavail);
150 printf("\tf_files: %ld\n", vfs.f_files);
151 printf("\tf_ffree: %ld\n", vfs.f_ffree);
152 printf("\tf_namelen: %ld\n", vfs.f_namelen);
153 }
Чтобы сохранить место, мы опустили main()
process ()
, которая теперь вызывает do_statfs()
вместо do_statvfs()
.Строки 13–35 содержат список магических чисел файловых систем из справочной страницы
type2str()
, которая преобразует магическое число в выводимую строку. Она осуществляет простой линейный поиск в таблице пар (значение, строка). В (маловероятном) случае, когда магическое число в таблице отсутствует, type2str()
создает сообщение «неизвестный тип» и возвращает его (строки 123–124).do_statfs()
struct statfs
. Член f_fsid
опущен, поскольку fsid_t
является непрозрачным типом. Код прост; строка 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
int chdir(const char *path); /* POSIX */
int fchdir(int fd); /* XSI */
Функция chdir()
fchdir()
ожидает дескриптор файла, который был открыт для каталога с помощью open()
.[83] Обе возвращают 0 при успехе и -1 при ошибке (с errno
, установленной соответствующим образом). Обычно, если open()
для каталога завершается успешно, fchdir()
также достигает цели, если кто-то не изменил права доступа к каталогу между вызовами, (fchdir()
сравнительно новая функция; на старых системах Unix ее нет.)