ioctl_fat(2) System Calls Manual ioctl_fat(2) ioctl_fat - FAT LIBRARY Standard C library (libc, -lc) #include /* Definition of [V]FAT_* and ATTR_* constants*/" #include 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). Linux. 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 Linux 3.11. ioctl(2) . . , . /mnt/user/foo: # ./toggle_fat_archive_flag /mnt/user/foo (toggle_fat_archive_flag.c) #include #include #include #include #include #include #include /* * 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 #include #include #include #include #include #include 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 #include #include #include #include #include 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 , Dmitriy S. Seregin , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . ioctl_fat(2)