ioctl_fat(2)

NOM
ioctl_fat - manipuler le système de fichiers FAT

BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)

SYNOPSIS
#include <linux/msdos_fs.h>     /* Définition des constantes
                                    [V]FAT_* et ATTR_* */"
#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]);

DESCRIPTION
L'appel système ioctl(2) peut être utilisé pour lire et écrire les métadonnées des systèmes de fichiers FAT non accessibles par d'autres appels systèmes.

  Lecture et définition des attributs de fichiers
Les fichiers et les répertoires d'un système de fichiers FAT possèdent un masque de bit d'attribut qu'on peut lire avec FAT_IOCTL_GET_ATTRIBUTES et écrire avec FAT_IOCTL_SET_ATTRIBUTES.

Le paramètre fd contient un descripteur de fichier pour un fichier ou un répertoire. Il suffit pour créer le descripteur de fichier en appelant open(2) avec l'attribut O_RDONLY.

Le paramètre attr contient un pointeur vers un masque de bit. Les bits du masque sont :

ATTR_RO
    Ce bit indique que le fichier ou le répertoire est en lecture seule.

ATTR_HIDDEN
    Ce bit indique que le fichier ou le répertoire est caché.

ATTR_SYS
    Ce bit indique que le fichier est un système de fichiers.

ATTR_VOLUME
    Ce bit indique que le fichier est une étiquette de volume. Cet attribut est en lecture seule.

ATTR_DIR
    Ce bit indique qu'il s'agit d'un répertoire. Cet attribut est en lecture seule.

ATTR_ARCH
    Ce bit indique que le fichier ou le répertoire doit être archivé. Il est positionné quand un fichier est créé ou modifié. Il est réinitialisé par un système d'archivage.

La valeur zéro ATTR_NONE peut être utilisée pour indiquer qu'aucun bit d'attribut n'est positionné.

  Lecture de l'identifiant du volume
Les systèmes de fichiers FAT sont identifiés par des identifiants de volume. L'identifiant de volume peut être lu avec FAT_IOCTL_GET_VOLUME_ID.

Le paramètre fd peut être un descripteur de fichier pour n'importe quel fichier ou répertoire du système de fichiers. Il suffit pour créer le descripteur de fichier en appelant open(2) avec l'attribut O_RDONLY.

Le paramètre id est un pointeur vers le champ qui sera rempli avec l'identifiant de volume. Généralement, l'identifiant de volume est montré à l'utilisateur sous la forme d'un groupe de deux champs de 16 bits :

    printf("Identifiant de volume %04x-%04x\n", id >> 16, id & 0xFFFF);

  Lecture des noms de fichier courts d'un répertoire
Un fichier ou un répertoire sur un système de fichiers FAT a toujours un nom de fichier court comportant jusqu'à 8 caractères en majuscules, éventuellement suivis d'un point et jusqu'à 3 caractères en majuscules pour l'extension de fichier. Si le nom de fichier ne correspond pas à ce schéma, il est stocké en tant que nom de fichier long jusqu'à 215 caractères en UTF-16.

Les noms de fichier courts d'un répertoire peuvent être lus avec VFAT_IOCTL_READDIR_SHORT. VFAT_IOCTL_READDIR_BOTH lit à la fois les noms de fichier longs et courts.

Le paramètre fd doit être le descripteur de fichier d'un répertoire. Il suffit pour créer le descripteur de fichier en appelant open(2) avec l'attribut O_RDONLY. Le descripteur de fichier ne peut être utilisé qu'une fois pour répéter les entrées d'un répertoire en appelant ioctl(2) plusieurs fois.

L'argument entry est un tableau de deux éléments des structures suivantes :

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

La première entrée du tableau est pour le nom de fichier court. La deuxième entrée est pour le nom de fichier long.

Les champs d_ino et d_off ne sont remplis que pour les noms de fichier longs. Le champ d_ino contient le numéro d'inœud du répertoire. Le champ d_off contient la position de l'entrée du fichier dans le répertoire. Ces valeurs n'étant pas disponibles pour les noms de fichier courts, le code de l'utilisateur doit simplement les ignorer.

Le champ d_reclen contient la longueur du nom de fichier inscrit dans le champ d_name. Pour assurer la rétro-compatibilité, une longueur de 0 pour un nom de fichier court signale que la fin du répertoire a été atteinte. Toutefois, la méthode privilégiée pour détecter la fin d'un répertoire consiste à tester le code de retour de ioctl(2). S'il n'existe pas de noms de fichier longs, le champ d_reclen est positionné à 0 et d_name est une chaîne de caractères de taille 0 pour les noms de fichier longs.

VALEUR RENVOYÉE
En cas d'erreur, la valeur de retour est -1 et errno est définie pour préciser l'erreur.

Pour VFAT_IOCTL_READDIR_BOTH et VFAT_IOCTL_READDIR_SHORT, le code de retour 1 signale qu'une nouvelle entrée de répertoire a été lue et un code de retour 0 indique que la fin du répertoire a été atteinte.

ERREURS

ENOENT
    Cette erreur est renvoyée par VFAT_IOCTL_READDIR_BOTH et VFAT_IOCTL_READDIR_SHORT si le descripteur de fichier fd se rapporte à un répertoire supprimé mais ouvert.

ENOTDIR
    Cette erreur est renvoyée par VFAT_IOCTL_READDIR_BOTH et VFAT_IOCTL_READDIR_SHORT si le descripteur de fichier fd ne se rapporte pas à un répertoire.

ENOTTY
    Le descripteur de fichier fd ne se rapporte pas à un objet d'un système de fichiers FAT.

Pour plus de codes d'erreur, voir ioctl(2).

STANDARDS
Linux.

HISTORIQUE

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.

EXEMPLES

  Basculer l'attribut d'archivage
Le programme suivant illustre l'utilisation de ioctl(2) pour manipuler les attributs des fichiers. Le programme lit et affiche l'attribut d'archivage d'un fichier. Après avoir inversé la valeur de l'attribut, le programme lit et affiche de nouveau l'attribut.

Ce qui suit a été enregistré lors de l'application du programme au fichier /mnt/user/foo :

    # ./toggle_fat_archive_flag /mnt/user/foo
    Archive flag is set
    Toggling archive flag
    Archive flag is not set

  Source du programme (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);
    }

  Lecture de l'identifiant du volume
Le programme suivant illustre l'utilisation de ioctl(2) pour afficher l'identifiant du volume d'un système de fichiers FAT.

L'affichage suivant a été enregistré lors de l'application du programme au répertoire /mnt/user :

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

  Source du programme (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);
    }

  Afficher le contenu d'un répertoire
Le programme suivant illustre l'utilisation de ioctl(2) pour afficher le contenu d'un répertoire.

Ce qui suit a été enregistré lors de l'application du programme au répertoire /mnt/user :

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

  Source du programme
    #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);
    }

VOIR AUSSI
ioctl(2)

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.