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

119  for (i = 0; table[i].type != 0; i++)

120   if (table[i].type == type)

121    return table[i].name;

122

123  sprintf(unknown, "unknown type: %#x", type);

124  return unknown;

125 }

126

127 /* do_statfs --- Использовать statfs и вывести сведения */

128

129 void do_statfs(const struct mntent *fs)

130 {

131  struct statfs vfs;

132

133  if (fs->mnt_fsname[0] != '/') /* пропустить фиктивные файловые системы */

134   return;

135

136  if (statfs(fs->mnt_dir, &vfs) != 0) {

137   fprintf(stderr, "%s: %s: statfs failed: %s\n",

138    myname, fs->mnt_dir, strerror(errno));

139   errors++;

140   return;

141  }

142

143  printf("%s, mounted on %s:\n", fs->mnt_dir, fs->mnt_fsname);

144

145  printf("\tf_type: %s\n", type2str(vfs.f_type));

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 содержат список магических чисел файловых систем из справочной страницы statfs(2). Хотя эти числа можно получить из заголовочных файлов исходного кода ядра, это трудно (мы пробовали), а показанному здесь способу представления следовать легче. Строки 86–125 определяют

type2str()
, которая преобразует магическое число в выводимую строку. Она осуществляет простой линейный поиск в таблице пар (значение, строка). В (маловероятном) случае, когда магическое число в таблице отсутствует,
type2str()
создает сообщение «неизвестный тип» и возвращает его (строки 123–124).

do_statfs()
(строки 129–153) выводит сведения из
struct statfs
. Член
f_fsid
опущен, поскольку
fsid_t
является непрозрачным типом. Код прост; строка 145 использует
type2str()
для вывода типа файловой системы. Как для сходной программы, использующей
statvfs()
, эта функция игнорирует файловые системы, которые не расположены на локальных устройствах (строки 133–134). Вот вывод на нашей системе:

$ <b>ch08-statfs</b> /* Запуск программы */

/, 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 <i>некоторое_место</i>
'.

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

#include &lt;unistd.h&gt;

int chdir(const char *path); /* POSIX */

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