Scroll to navigation

ioctl_fat(2) System Calls Manual ioctl_fat(2)

ИМЯ

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

БИБЛИОТЕКА

Стандартная библиотека языка C (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).

ВЕРСИИ

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 (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.

10 февраля 2023 г. Справочные страницы Linux 6.03