# VFAT_IOCTL_READDIR_BOTH

## NAME



           VFAT_IOCTL_READDIR_BOTH, VFAT_IOCTL_READDIR_SHORT - read filenames
           of a directory in a FAT filesystem
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#include <linux/msdos_fs.h>  **/* Definition of **VFAT_*** constants */
           **#include <sys/ioctl.h>**
    
           **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



           A file or directory on a FAT filesystem always has a short
           filename consisting of up to 8 capital letters, optionally
           followed by a period and up to 3 capital letters for the file
           extension.  If the actual filename does not fit into this scheme,
           it is stored as a long filename of up to 255 UTF-16 characters.
    
           The short filenames in a directory can be read with
           **VFAT_IOCTL_READDIR_SHORT**.  **VFAT_IOCTL_READDIR_BOTH** reads both the
           short and the long filenames.
    
           The _fd_ argument must be a file descriptor for a directory.  It is
           sufficient to create the file descriptor by calling open(2) with
           the **O_RDONLY** flag.  The file descriptor can be used only once to
           iterate over the directory entries by calling ioctl(2) repeatedly.
    
           The _entry_ argument is a two-element array of the following
           structures:
    
               struct __fat_dirent {
                   long            d_ino;
                   __kernel_off_t  d_off;
                   uint32_t short  d_reclen;
                   char            d_name[256];
               };
    
           The first entry in the array is for the short filename.  The
           second entry is for the long filename.
    
           The _d_ino_ and _d_off_ fields are filled only for long filenames.
           The _d_ino_ field holds the inode number of the directory.  The
           _d_off_ field holds the offset of the file entry in the directory.
           As these values are not available for short filenames, the user
           code should simply ignore them.
    
           The field _d_reclen_ contains the length of the filename in the
           field _d_name_.  To keep backward compatibility, a length of 0 for
           the short filename signals that the end of the directory has been
           reached.  However, the preferred method for detecting the end of
           the directory is to test the ioctl(2) return value.  If no long
           filename exists, field _d_reclen_ is set to 0 and _d_name_ is a
           character string of length 0 for the long filename.
    


## RETURN VALUE



           A return value of 1 signals that a new directory entry has been
           read and a return value of 0 signals that the end of the directory
           has been reached.
    
           On error, -1 is returned, and _errno_ is set to indicate the error.
    


## ERRORS



           **ENOENT** _fd_ refers to a removed, but still open directory.
    
           **ENOTDIR**
                  _fd_ does not refer to a directory.
    


## STANDARDS



           Linux.
    


## EXAMPLES



           The following program demonstrates the use of ioctl(2) to list a
           directory.
    
           The following was recorded when applying the program to the
           directory _/mnt/user_ :
    
               $ **./fat_dir /mnt/user** ;
               . -> ''
               .. -> ''
               ALONGF~1.TXT -> 'a long filename.txt'
               UPPER.TXT -> ''
               LOWER.TXT -> 'lower.txt'
    
       **Program source**
           #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);
           }
    


* * *