#include <sys/syscall.h> /* Définition des constantes SYS_* */ #include <unistd.h> long syscall(SYS_getdents, unsigned int fd, struct linux_dirent *dirp, unsigned int count); #define _GNU_SOURCE /* Voir feature_test_macros(7) */ #include <dirent.h> ssize_t getdents64(int fd, void dirp[.count], size_t count);
Remarque : la glibc ne fournit pas de fonction autour de getdents(), nécessitant l'utilisation de syscall(2).
Remarque : il n'existe pas de définition de struct linux_dirent dans la glibc ; voir les NOTES.
La structure linux_dirent est déclarée comme ceci :
struct linux_dirent {
unsigned long d_ino; /* Numéro d'inœud */
unsigned long d_off; /* Distance au prochain linux_dirent */
unsigned short d_reclen; /* Longueur de ce linux_dirent */
char d_name[]; /* Nom de fichier (fini par NULL) */
/* La longueur est en fait (d_reclen - 2 -
offsetof(struct linux_dirent, d_name)) */
/*
char pad; // Octet de remplissage avec des zéros
char d_type; // Type de fichier (seulement depuis
// Linux 2.6.4) ; sa position est
// (d_reclen - 1)
*/
d_ino est un numéro d'inœud. d_off est la distance entre le début du répertoire et le début de la prochaine structure linux_dirent. d_reclen est la taille complète de linux_dirent. d_name est le nom de fichier terminé par un caractère NULL.
d_type est un octet placé à la fin de la structure qui indique le type du fichier. Il contient l'une des valeurs suivantes (définies dans <dirent.h>) :
Le champ d_type est implémenté depuis Linux 2.6.4. Il occupe un espace qui était auparavant un octet de remplissage composé de zéros dans la structure linux_dirent. Ainsi, sur les noyaux antérieurs ou égaux à 2.6.3, les accès à ce champ fournissent toujours la valeur 0 (DT_UNKNOWN).
Actuellement, seuls certains systèmes de fichiers (parmi lesquels Btrfs, ext2, ext3 et ext4) prennent complètement en charge le renvoi du type de fichier dans d_type. Toutes les applications doivent gérer correctement une valeur de retour valant DT_UNKNOWN.
L'appel système getdents64() est comme getdents(), sauf que son deuxième paramètre est un pointeur vers un tampon contenant des structures de type suivant :
struct dirent {
ino_t d_ino; /* numéro d'inœud 64 bits */
off_t d_off; /* distance 64 bits vers
la prochaine structure */
unsigned short d_reclen; /* longueur de ce dirent */
unsigned char d_type; /* type du fichier */
char d_name[]; /* nom du fichier (terminé par NULL) */
};
Vous voudrez probablement utiliser readdir(3) à la place de ces appels système.
Ces appels remplacent readdir(2).
$ ./a.out /testfs/
--------------- nread=120 ---------------
inode# file type d_reclen d_off d_name
2 directory 16 12 .
2 directory 16 24 ..
11 directory 24 44 lost+found
12 regular 16 56 a
228929 directory 16 68 sub
16353 directory 16 80 sub2
130817 directory 16 4096 sub3
struct linux_dirent {
unsigned long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[];
};
#define BUF_SIZE 1024
int
main(int argc, char *argv[])
{
int fd;
char d_type;
char buf[BUF_SIZE];
long nread;
struct linux_dirent *d;
fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
if (fd == -1)
err(EXIT_FAILURE, "open");
for (;;) {
nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
if (nread == -1)
err(EXIT_FAILURE, "getdents");
if (nread == 0)
break;
printf("--------------- nread=%ld ---------------\n", nread);
printf("inoeud# tupe de fichier d_reclen d_off d_name\n");
for (size_t bpos = 0; bpos < nread;) {
d = (struct linux_dirent *) (buf + bpos);
printf("%8lu ", d->d_ino);
d_type = *(buf + bpos + d->d_reclen - 1);
printf("%-10s ", (d_type == DT_REG) ? "régulier" :
(d_type == DT_DIR) ? "répertoire" :
(d_type == DT_FIFO) ? "FIFO" :
(d_type == DT_SOCK) ? "socket" :
(d_type == DT_LNK) ? "liens symboliques" :
(d_type == DT_BLK) ? "bloc de périph" :
(d_type == DT_CHR) ? "char dev" : "???");
printf("%4d %10jd %s\n", d->d_reclen,
(intmax_t) d->d_off, d->d_name);
bpos += d->d_reclen;
}
}
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 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 à