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

Некоторые из этих масок служат цели изолирования различных наборов битов, закодированных в поле

st_mode
:

• 

S_IFMT
представляет биты 12–15, которыми закодированы различные типы файлов.

• 

S_IRWXU
представляет биты 6–8, являющиеся правами доступа владельца (на чтение, запись, исполнение для User).

• 

S_IRWXG
представляет биты 3–5, являющиеся правами доступа группы (на чтение, запись, исполнение для Group).

• 

S_IRWXO
представляет биты 0–2, являющиеся правами доступа для «остальных» (на чтение, запись, исполнение для Other).

Биты прав доступа и типа файла графически изображены на рис. 5.3.

Linux программирование в примерах - img_9.jpeg

Рис. 5.3. Биты прав доступа и типа файлов

Маски типов файлов стандартизованы главным образом для совместимости со старым кодом; они не должны использоваться непосредственно, поскольку такой код менее читаем, чем соответствующие макросы. Случается, что макрос реализован с использованием масок: довольно логично, но это не подходит для кода уровня пользователя.

Стандарт POSIX явным образом констатирует; что в будущем не будут стандартизированы новые битовые маски и что тесты для любых дополнительных разновидностей типов файлов, которые могут быть добавлены, будут доступны лишь в виде макросов

S_IS<i>xxx</i>()
.

5.4.4.1. Сведения об устройстве

Стандарт POSIX не определяет значение типа

dev_t
, поскольку предполагалось его использование на не-Unix системах также, как на Unix-системах. Однако стоит знать, что находится в
dev_t
.

Когда истинно

S_ISBLK(sbuf.st_mode)
или
S_ISCHR(sbuf.st_mode)
, сведения об устройстве находятся в поле
sbuf.st_rdev
. В противном случае это поле не содержит никакой полезной информации.

Традиционно файлы устройств Unix кодируют старший и младший номера устройства в значении

dev_t
. По старшему номеру различают тип устройства, такой, как «дисковый привод» или «ленточный привод». Старшие номера различают также разные типы устройств, такие, как диск SCSI в противоположность диску IDE. Младшие номера различают устройства данного типа, например, первый диск или второй. Вы можете увидеть эти значения с помощью '
ls -l
':

$ <b>ls -l /dev/hda /dev/hda?</b> /* Показать номера для первого жесткого диска */

brw-rw---- 1 root disk 3, 0 Aug 31 2002 /dev/hda

brw-rw---- 1 root disk 3, 1 Aug 31 2002 /dev/hda1

brw-rw---- 1 root disk 3, 2 Aug 31 2002 /dev/hda2

brw-rw---- 1 root disk 3, 3 Aug 31 2002 /dev/hda3

brw-rw---- 1 root disk 3, 4 Aug 31 2002 /dev/hda4

brw-rw---- 1 root disk 3, 5 Aug 31 2002 /dev/hda5

brw-rw---- 1 root disk 3, 6 Aug 31 2002 /dev/hda6

brw-rw---- 1 root disk 3, 7 Aug 31 2002 /dev/hda7

brw-rw---- 1 root disk 3, 8 Aug 31 2002 /dev/hda8

brw-rw---- 1 root disk 3, 9 Aug 31 2002 /dev/hda9

$ <b>ls -l /dev/null</b> /* Показать сведения также для /dev/null */

crw-rw-rw- 1 root root 1, 3 Aug 31 2002 /dev/null

Вместо размера файла

ls
отображает старший и младший номера. В случае жесткого диска
/dev/hda
представляет диск в целом,
/dev/hda1
,
/dev/hda2
и т.д. представляют разделы внутри диска. У них у всех общий старший номер устройства (3), но различные младшие номера устройств.

Обратите внимание, что дисковые устройства являются блочными устройствами, тогда как

/dev/null
является символьным устройством. Блочные и символьные устройства являются отдельными сущностями; даже если символьное устройство и блочное устройство имеют один и тот же старший номер устройства, они необязательно связаны

Старший и младший номера устройства можно извлечь из значения

dev_t
с помощью функций
major()
и
minor()
, определенных в
&lt;sys/sysmacros.h&gt;
:

#include &lt;sys/types.h&gt; /* Обычный */

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

int major(dev_t dev);                /* Старший номер устройства */

int minor(dev_t dev);                /* Младший номер устройства */

dev_t makedev(int major, int minor); /* Создать значение dev_t */

(Некоторые системы реализуют их в виде макросов.)

Функция

makedev()
идет другим путем; она принимает отдельные значения старшего и младшего номеров и кодирует их в значении
dev_t
. В других отношениях ее использование выходит за рамки данной книги; патологически любопытные должны посмотреть mknod(2).

Следующая программа,

ch05-devnum.c
, показывает, как использовать системный вызов
stat()
, макросы проверки типа файла и, наконец, макросы
major()
и
minor()
.

/* ch05-devnum.c --- Демонстрация stat(), major(), minor(). */

#include &lt;stdio.h&gt;

#include &lt;errno.h&gt;

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

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

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

int main(int argc, char **argv) {

 struct stat sbuf;

 char *devtype;

 if (argc != 2) {

  fprintf(stderr, &quot;usage: %s path\n&quot;, argv[0]);

  exit(1);

 }

 if (stat(argv[1], &amp;sbuf) &lt; 0) {

  fprintf(stderr, &quot;%s: stat: %s\n&quot;, argv[1], strerror(errno));

  exit(1);

 }

 if (S_ISCHR(sbuf.st_mode))

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