Linux программирование в примерах
Некоторые из этих масок служат цели изолирования различных наборов битов, закодированных в поле
:st_mode•
представляет биты 12–15, которыми закодированы различные типы файлов.S_IFMT•
представляет биты 6–8, являющиеся правами доступа владельца (на чтение, запись, исполнение для User).S_IRWXU•
представляет биты 3–5, являющиеся правами доступа группы (на чтение, запись, исполнение для Group).S_IRWXG•
представляет биты 0–2, являющиеся правами доступа для «остальных» (на чтение, запись, исполнение для Other).S_IRWXOБиты прав доступа и типа файла графически изображены на рис. 5.3.
Рис. 5.3. Биты прав доступа и типа файлов
Маски типов файлов стандартизованы главным образом для совместимости со старым кодом; они не должны использоваться непосредственно, поскольку такой код менее читаем, чем соответствующие макросы. Случается, что макрос реализован с использованием масок: довольно логично, но это не подходит для кода уровня пользователя.
Стандарт POSIX явным образом констатирует; что в будущем не будут стандартизированы новые битовые маски и что тесты для любых дополнительных разновидностей типов файлов, которые могут быть добавлены, будут доступны лишь в виде макросов
.S_IS<i>xxx</i>()5.4.4.1. Сведения об устройстве
Стандарт POSIX не определяет значение типа
, поскольку предполагалось его использование на не-Unix системах также, как на Unix-системах. Однако стоит знать, что находится вdev_t.dev_tКогда истинно
илиS_ISBLK(sbuf.st_mode), сведения об устройстве находятся в полеS_ISCHR(sbuf.st_mode). В противном случае это поле не содержит никакой полезной информации.sbuf.st_rdevТрадиционно файлы устройств Unix кодируют старший и младший номера устройства в значении
. По старшему номеру различают тип устройства, такой, как «дисковый привод» или «ленточный привод». Старшие номера различают также разные типы устройств, такие, как диск SCSI в противоположность диску IDE. Младшие номера различают устройства данного типа, например, первый диск или второй. Вы можете увидеть эти значения с помощью 'dev_t':ls -l$ <b>ls -l /dev/hda /dev/hda?</b> /* Показать номера для первого жесткого диска */brw-rw---- 1 root disk 3, 0 Aug 31 2002 /dev/hdabrw-rw---- 1 root disk 3, 1 Aug 31 2002 /dev/hda1brw-rw---- 1 root disk 3, 2 Aug 31 2002 /dev/hda2brw-rw---- 1 root disk 3, 3 Aug 31 2002 /dev/hda3brw-rw---- 1 root disk 3, 4 Aug 31 2002 /dev/hda4brw-rw---- 1 root disk 3, 5 Aug 31 2002 /dev/hda5brw-rw---- 1 root disk 3, 6 Aug 31 2002 /dev/hda6brw-rw---- 1 root disk 3, 7 Aug 31 2002 /dev/hda7brw-rw---- 1 root disk 3, 8 Aug 31 2002 /dev/hda8brw-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и т.д. представляют разделы внутри диска. У них у всех общий старший номер устройства (3), но различные младшие номера устройств./dev/hda2Обратите внимание, что дисковые устройства являются блочными устройствами, тогда как
является символьным устройством. Блочные и символьные устройства являются отдельными сущностями; даже если символьное устройство и блочное устройство имеют один и тот же старший номер устройства, они необязательно связаны/dev/nullСтарший и младший номера устройства можно извлечь из значения
с помощью функцийdev_tиmajor(), определенных вminor():<sys/sysmacros.h>#include <sys/types.h> /* Обычный */#include <sys/sysmacros.h>int major(dev_t dev); /* Старший номер устройства */int minor(dev_t dev); /* Младший номер устройства */dev_t makedev(int major, int minor); /* Создать значение dev_t */(Некоторые системы реализуют их в виде макросов.)
Функция
идет другим путем; она принимает отдельные значения старшего и младшего номеров и кодирует их в значенииmakedev(). В других отношениях ее использование выходит за рамки данной книги; патологически любопытные должны посмотреть mknod(2).dev_tСледующая программа,
, показывает, как использовать системный вызовch05-devnum.c, макросы проверки типа файла и, наконец, макросыstat()иmajor().minor()/* ch05-devnum.c --- Демонстрация stat(), major(), minor(). */#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/sysmacros.h>int main(int argc, char **argv) {struct stat sbuf;char *devtype;if (argc != 2) {fprintf(stderr, "usage: %s path\n", argv[0]);exit(1);}if (stat(argv[1], &sbuf) < 0) {fprintf(stderr, "%s: stat: %s\n", argv[1], strerror(errno));exit(1);}if (S_ISCHR(sbuf.st_mode))
