ioctl_fat(2) System Calls Manual ioctl_fat(2)

ИМЯ

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

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_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, когда достигнут конец каталога.

ОШИБКИ

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

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

СТАНДАРТЫ

Linux.

ИСТОРИЯ

Linux 2.0.
Linux 2.6.12.
Linux 3.11.

ПРИМЕРЫ

Переключение флага архивирования

В следующей программе показано использование 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>
/*
 * Read file attributes of a file on a FAT filesystem.
 * Output the state of the archive flag.
 */
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("Archive flag is set\n");
    else
        printf("Archive flag is not set\n");
    return attr;
}
int
main(int argc, char *argv[])
{
    int       fd;
    int       ret;
    uint32_t  attr;
    if (argc != 2) {
        printf("Usage: %s FILENAME\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    /*
     * Read and display the FAT file attributes.
     */
    attr = readattr(fd);
    /*
     * Invert archive attribute.
     */
    printf("Toggling archive flag\n");
    attr ^= ATTR_ARCH;
    /*
     * Write the changed FAT file attributes.
     */
    ret = ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
    if (ret == -1) {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    /*
     * Read and display the FAT file attributes.
     */
    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("Usage: %s FILENAME\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    /*
     * Read volume ID.
     */
    ret = ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &id);
    if (ret == -1) {
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    /*
     * Format the output as two groups of 16 bits each.
     */
    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("Usage: %s DIRECTORY\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    /*
     * Open file descriptor for the directory.
     */
    fd = open(argv[1], O_RDONLY | O_DIRECTORY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    for (;;) {
        /*
         * Read next directory entry.
         */
        ret = ioctl(fd, VFAT_IOCTL_READDIR_BOTH, entry);
        /*
         * If an error occurs, the return value is -1.
         * If the end of the directory list has been reached,
         * the return value is 0.
         * For backward compatibility the end of the directory
         * list is also signaled by 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 the file descriptor.
     */
    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.

31 октября 2023 г. Linux man-pages 6.06