Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
ЗАМЕЧАНИЕ. Хотя POSIX определяет
statvfs()fstatvfs()df#ifdefОбычной методикой, применимой во многих случаях, является использование набора значений флагов; когда флаг установлен (т.е. true), имеет место некоторый факт или применяется некоторое условие. Значения флагов определены либо через именованные константы
#definenftw()f_flagstruct statvfs#define ST_RDONLY 1 /* файловая система только для чтения */#define ST_NOSUID 2 /* setuid/setgid не разрешены */Физически каждая именованная константа представляет различные позиции битов в значении
f_flagstruct statvfsФлаги устанавливаются, проверяются и очищаются с помощью побитовых операторов С. Например,
statvfs()int statvfs(const char *path, struct statvfs *vfs) { /* заполнить большую часть *vfs */ vfs->f_flag = 0; /* Убедиться, что начинается с нуля */ if (<i>файловая система только для чтения</i>) vfs->f_flag |= ST_RDONLY; /* Добавить флаг ST_RDONLY */ if (<i>файловая система запрещает setuid</i>) vfs->f_flag |= ST_NOSUID; /* Добавить флаг ST_NOSUID */ /* оставшаяся часть процедуры */}Побитовый оператор И проверяет, установлен ли флаг, а сочетание побитовых операторов И и дополнения очищает флаг:
if ((vfs.f_flag & ST_RDONLY) != 0) /* True, если флаг ST_RDONLY */ vfs.f_flag &= ~(ST_RDONLY|ST_NOSUID); /* Очистить оба флага */Побитовые операторы отпугивают, если вы не использовали их ранее. Однако, только что показанный код примера представляет обычный стиль С. Тщательно изучите каждую операцию; возможно, нарисуйте себе несколько картин, показывающих работу этих операторов. Однажды разобравшись с ними, вы можете тренировать себя, распознавая эти операторы как высокоуровневые операции для управления значениями флагов вместо их трактовки как низкоуровневых манипуляций с битами.
Причина использования флагов кроется в том, что они обеспечивают значительную экономию пространства данных. Одно поле
unsigned longf_flagcharunsigned long8.3.2. Стиль Linux:
statfs()fstatfs()Системные вызовы
statfs()fstatfs()#include <sys/types.h> /* GLIBC */#include <sys/vfs.h>int statfs(const char *path, struct statfs *buf);int fstatfs(int fd, struct statfs *buf);Как и в случае с
statvfs()fstatvfs()struct statfs { long f_type; /* тип файловой системы */ long f_bsize; /* оптимальный размер блока */ long f_blocks; /* общее число блоков в файловой системе */ long f_bfree; /* число свободных блоков в ф.с. */ long f_bavail; /* свободные блоки, доступные пользователям */ long f_files; /* общее число индексов в файловой системе */ long f_ffree; /* свободных индексов в ф.с. */ fsid_t f_fsid; /* id файловой системы */ long f_namelen; /* максимальная длина имен файлов */ long f_spare[6]; /* запас для дальнейшего */};Поля аналогичны полям в
struct statvfsstatvfs()fstatvfs()statfs()fstatfs()Преимуществом использования
statfs()fstatfs()f_flagstatfvs()pathfdstatfs()