Provided by: manpages-ru-dev_4.21.0-2_all bug

ИМЯ

       ioctl_fat - управление файловой системой FAT

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <linux/msdos_fs.h>     /* Definition of [V]FAT_* and
                                          ATTR_* constants*/"
       #include <sys/ioctl.h>

       int ioctl(int fd, FAT_IOCTL_GET_ATTRIBUTES, uint32_t *attr);
       int ioctl(int fd, FAT_IOCTL_SET_ATTRIBUTES, uint32_t *attr);
       int ioctl(int fd, FAT_IOCTL_GET_VOLUME_ID, uint32_t *id);
       int ioctl(int fd, VFAT_IOCTL_READDIR_BOTH,
                 struct __fat_dirent entry[2]);
       int ioctl(int fd, VFAT_IOCTL_READDIR_SHORT,
                 struct __fat_dirent entry[2]);

ОПИСАНИЕ

       Системный  вызов  ioctl(2) можно использовать для чтения и записи метаданных файловых систем FAT, которые
       недоступны через другие системные вызовы.

   Чтение и установка файловых атрибутов
       У файлов и каталогов и в файловой системе FAT есть битовая маска атрибутов,  которую  можно  прочитать  с
       помощью FAT_IOCTL_GET_ATTRIBUTES и записать с FAT_IOCTL_SET_ATTRIBUTES.

       Аргумент  fd  содержит  файловый  дескриптор  файла  или  каталога.  Для  создания  файлового дескриптора
       достаточно вызвать open(2) с флагом O_RDONLY.

       Аргумент attr содержит указатель на битовую маску. Назначение битов в маске:

       ATTR_RO
              Данный бит означает, что файл или каталог доступен только для чтения.

       ATTR_HIDDEN
              Данный бит означает, что файл или каталог скрыт.

       ATTR_SYS
              Данный бит означает, что файл является системным.

       ATTR_VOLUME
              Данный бит означает, что файл является меткой тома. Данный атрибут доступен только для чтения.

       ATTR_DIR
              Данный бит означает, что это каталог. Данный атрибут доступен только для чтения.

       ATTR_ARCH
              Данный бит означает, что файл или каталог должны архивироваться. Он устанавливается  при  создании
              или изменении файла. Он сбрасывается системой архивирования.

       Нулевое значение ATTR_NONE можно использовать для указания, что все биты атрибутов не установлены.

   Чтение идентификатора тома
       Файловые  системы  FAT маркируются идентификатором тома. Идентификатор тома может быть прочитан с помощью
       FAT_IOCTL_GET_VOLUME_ID.

       Аргумент fd может быть файловым дескриптором файла или каталога файловой системы. Для создания  файлового
       дескриптора достаточно вызвать open(2) с флагом O_RDONLY.

       Аргумент id — это указатель на поле, которое будет заполнено ID тома. Обычно, идентификатор тома выдаётся
       пользователю как группа из двух 16-битных полей:

           printf("Volume ID %04x-%04x\n", id >> 16, id & 0xFFFF);

   Чтение коротких имён файлов каталога
       Файл  или  каталог  файловой  системы  FAT  всегда  имеет короткое имя файла, состоящее из не более чем 8
       заглавных букв, необязательной точки и до 3 заглавных букв расширения файла. Если реальное имя  файла  не
       следует такой схеме, то оно сохраняется как длинное имя файла — до 255 символов UTF-16.

       Короткие  имена  файлов  в  каталоге  можно  прочитать  с  помощью  VFAT_IOCTL_READDIR_SHORT.  С  помощью
       VFAT_IOCTL_READDIR_BOTH можно прочитать как короткие так и длинные имена файлов.

       Аргумент fd должен содержать файловый дескриптор каталога. Для создания файлового дескриптора  достаточно
       вызвать  open(2) с флагом O_RDONLY. Файловый дескриптор можно использовать только однажды для обхода всех
       элементов каталога повторными вызовами ioctl(2).

       Параметр info представляет собой двухэлементный массив структур следующего вида:

           struct __fat_dirent {
               long            d_ino;
               __kernel_off_t  d_off;
               uint32_t short  d_reclen;
               char            d_name[256];
           };

       Первый элемент массива содержит короткое имя файла. Во втором содержится длинное имя файла.

       Поля d_ino и d_off заполняются только для длинных имён. Поле d_ino содержит номер  inode  каталога.  Поле
       d_off  содержит  смещение  записи  файла  в  каталоге.  Так  как  эти  поля недоступны для коротких имён,
       пользовательский код должен просто игнорировать их.

       В поле d_reclen содержится длина имени файла из поля d_name. Для сохранения обратной совместимости  длина
       0 для короткого имени указывает на достижение конца каталога. Однако предпочтительным методом определения
       конца каталога является проверка возвращаемого ioctl(2) значения. Если длинное имя не существует, то поле
       d_reclen устанавливается в 0 и d_name — строка символов длиной 0 для длинного имени файла.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.

       При использовании VFAT_IOCTL_READDIR_BOTH и VFAT_IOCTL_READDIR_SHORT возвращается значение 1, означающее,
       что был прочитан новый элемент каталога и 0, когда достигнут конец каталога.

ОШИБКИ

       ENOENT Данная  ошибка  может  возвращаться  при  VFAT_IOCTL_READDIR_BOTH и VFAT_IOCTL_READDIR_SHORT, если
              файловый дескриптор fd указывает на на удалённый, но ещё открытый каталог.

       ENOTDIR
              Данная ошибка может возвращаться  при  VFAT_IOCTL_READDIR_BOTH  и  VFAT_IOCTL_READDIR_SHORT,  если
              файловый дескриптор fd не указывает на каталог.

       ENOTTY Файловый дескриптор fd указывает не на объект в файловой системе FAT.

       Дополнительные значения ошибок смотрите в ioctl(2).

ВЕРСИИ

       VFAT_IOCTL_READDIR_BOTH и VFAT_IOCTL_READDIR_SHORT впервые появились в Linux 2.0.

       FAT_IOCTL_GET_ATTRIBUTES и FAT_IOCTL_SET_ATTRIBUTES впервые появились в Linux 2.6.12.

       FAT_IOCTL_GET_VOLUME_ID появился в версии 3.11 ядра Linux.

СТАНДАРТЫ

       Данный программный интерфейс существует только в Linux.

ПРИМЕРЫ

   Переключение флага архивирования
       В  следующей программе показано использование ioctl(2) для изменения атрибутов файлов. Программа читает и
       показывает атрибут архивирования файла. После изменения значения атрибута на  противоположный,  программа
       читает и показывает атрибут ещё раз.

       Пример сеанса работы программы с файлом /mnt/user/foo:

           # ./toggle_fat_archive_flag /mnt/user/foo
           Флаг архивирования установлен
           Переключение флага архивирования
           Флаг архивирования сброшен

   Исходный код программы (toggle_fat_archive_flag.c)

       #include <fcntl.h>
       #include <linux/msdos_fs.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/ioctl.h>
       #include <unistd.h>

       /*
        * Читает атрибуты файла в файловой системе FAT.
        * Выводит состояние флага архивирования.
        */
       static uint32_t
       readattr(int fd)
       {
           int       ret;
           uint32_t  attr;

           ret = ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attr);
           if (ret == -1) {
               perror("ioctl");
               exit(EXIT_FAILURE);
           }

           if (attr & ATTR_ARCH)
               printf("Флаг архивирования установлен\n");
           else
               printf("Флаг архивирования сброшен\n");

           return attr;
       }

       int
       main(int argc, char *argv[])
       {
           int       fd;
           int       ret;
           uint32_t  attr;

           if (argc != 2) {
               printf("Использование: %s ИМЯ_ФАЙЛА\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDONLY);
           if (fd == -1) {
               perror("open");
               exit(EXIT_FAILURE);
           }

           /*
            * Читает и показывает атрибуты файлов в FAT.
            */
           attr = readattr(fd);

           /*
            * Invert archive attribute.
            */
           printf("Toggling archive flag\n");
           attr ^= ATTR_ARCH;

           /*
            * Записывает изменённые атрибуты файлов в FAT.
            */
           ret = ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
           if (ret == -1) {
               perror("ioctl");
               exit(EXIT_FAILURE);
           }

           /*
            * Читает и показывает атрибуты файлов в FAT.
            */
           readattr(fd);

           close(fd);

           exit(EXIT_SUCCESS);
       }

   Чтение идентификатора тома
       Следующий  пример  кода  демонстрирует  использование  ioctl(2)  для  вывода идентификатора тома файловой
       системы FAT.

       Пример сеанса работы программы с файлом /mnt/user:

           $ ./display_fat_volume_id /mnt/user
           Volume ID 6443-6241

   Исходный код программы (display_fat_volume_id.c)

       #include <fcntl.h>
       #include <linux/msdos_fs.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/ioctl.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           int       fd;
           int       ret;
           uint32_t  id;

           if (argc != 2) {
               printf("Использование: %s ИМЯ_ФАЙЛА\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDONLY);
           if (fd == -1) {
               perror("open");
               exit(EXIT_FAILURE);
           }

           /*
            * Читает ID тома.
            */
           ret = ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &id);
           if (ret == -1) {
               perror("ioctl");
               exit(EXIT_FAILURE);
           }

           /*
            * Форматирует вывод в виде двух групп по 16 бит каждая.
            */
           printf("Volume ID %04x-%04x\n", id >> 16, id & 0xFFFF);

           close(fd);

           exit(EXIT_SUCCESS);
       }

   Вывод содержимого каталога
       Следующий пример кода демонстрирует использование ioctl(2) для вывода содержимого каталога.

       Пример сеанса работы программы с файлом /mnt/user:

           $ ./fat_dir /mnt/user
           . -> ''
           .. -> ''
           ALONGF~1.TXT -> 'a long filename.txt'
           UPPER.TXT -> ''
           LOWER.TXT -> 'lower.txt'

   Исходный код программы
           #include <fcntl.h>
           #include <linux/msdos_fs.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <sys/ioctl.h>
           #include <unistd.h>

           int
           main(int argc, char *argv[])
           {
               int                  fd;
               int                  ret;
               struct __fat_dirent  entry[2];

               if (argc != 2) {
                   printf("Использование: %s КАТАЛОГ\n", argv[0]);
                   exit(EXIT_FAILURE);
               }

               /*
                * Открывает файловый дескриптор каталога.
                */
               fd = open(argv[1], O_RDONLY | O_DIRECTORY);
               if (fd == -1) {
                   perror("open");
                   exit(EXIT_FAILURE);
               }

               for (;;) {

                   /*
                    * Читает следующий элемент из каталога.
                    */
                   ret = ioctl(fd, VFAT_IOCTL_READDIR_BOTH, entry);

                   /*
                    * Если произошла ошибка, то возвращает -1.
                    * Если достигнут конец каталога, то
                    * возвращает 0.
                    * Для обратной совместимости при достижении конца каталога
                    * также d_reclen == 0.
                    */
                   if (ret < 1)
                       break;

                   /*
                    * Write both the short name and the long name.
                    */
                   printf("%s -> '%s'\n", entry[0].d_name, entry[1].d_name);
               }

               if (ret == -1) {
                   perror("VFAT_IOCTL_READDIR_BOTH");
                   exit(EXIT_FAILURE);
               }

               /*
                * Закрывает файловый дескриптор.
                */
               close(fd);

               exit(EXIT_SUCCESS);
           }

СМ. ТАКЖЕ

       ioctl(2)

ПЕРЕВОД

       Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy
       S. Seregin <dseregin@59.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

       Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3
       или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное  письмо
       на man-pages-ru-talks@lists.sourceforge.net.

Linux man-pages 6.03                           10 февраля 2023 г.                                   ioctl_fat(2)