du est une commande pour afficher la capacité du répertoire. Si vous l'utilisez sans options, il affichera toutes les capacités du répertoire sous le répertoire courant. Cette fois, je vais suivre l'implémentation pour voir comment la fonction est réalisée.
En tant que comportement, ce serait bien s'il y avait une fonction pour tracer le répertoire et y ajouter la taille du fichier. Pour cela, les fonctions suivantes sont susceptibles d'être nécessaires.
Regardons la mise en œuvre, en nous concentrant sur la façon dont ces fonctionnalités sont réalisées.
Cette fois, nous allons regarder le code source de du.c inclus dans GNU coreutils.
La fonction principale appelle du_files ()
.
python
/* Recursively print the sizes of the directories (and, if selected, files)
named in FILES, the last entry of which is NULL.
BIT_FLAGS controls how fts works.
Return true if successful. */
static bool
du_files (char **files, int bit_flags)
{
bool ok = true;
if (*files)
{
FTS *fts = xfts_open (files, bit_flags, NULL); //(1)
while (1)
{
FTSENT *ent;
ent = fts_read (fts); //(2)
if (ent == NULL)
{
if (errno != 0)
{
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
FTS_CROSS_CHECK (fts);
ok &= process_file (fts, ent); //(3)
}
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
}
return ok;
}
Le traitement effectué ici est le suivant.
(1). Récupérez la structure FTS du nom de fichier avec xfts_open ()
.
(2). Récupérez la structure FTSENT de la structure FTS avec fts_read ()
.
(3). Appelez process_file ()
et revenez à (2).
xfts_open()
Xfts_open ()
dans (1) est un wrapper pour fts_open ()
et en interne fts_open ()
est appelé. L'argument passé à xfts_open ()
est le nom du fichier. Ce nom de fichier est spécifié par l'argument de ligne de commande, et s'il n'y a pas d'argument, le répertoire courant est passé.
La structure FTS obtenue par xfts_open ()
est un handle de la hiérarchie des fichiers. Le champ a une structure FTSENT qui représente des informations sur le fichier et a la position actuelle et les structures FTSENT enfant. Chaque fois que vous appelez fts_read ()
dans (2), ils changent et suivent la hiérarchie des fichiers (voir ci-dessous).
fts_read()
Dans (2) fts_read ()
, la structure FTSENT à la position actuelle est obtenue à partir de la structure FTS. La structure FTSENT contient les champs suivants (fts).
python
typedef struct _ftsent {
unsigned short fts_info; /*Drapeaux pour les structures FTSENT*/
char *fts_accpath; /*Chemin d'accès*/
char *fts_path; /*Chemin racine*/
short fts_pathlen; /* fts_longueur du trajet*/
char *fts_name; /*nom de fichier*/
short fts_namelen; /* fts_longueur du nom*/
short fts_level; /*profondeur(-1 〜 N) */
int fts_errno; /*Numéro d'erreur de fichier*/
long fts_number; /*Nombre local*/
void *fts_pointer; /*Numéro d'adresse locale*/
struct ftsent *fts_parent; /*Dossier Parent*/
struct ftsent *fts_link; /*La structure de fichiers suivante*/
struct ftsent *fts_cycle; /*Structure en circulation*/
struct stat *fts_statp; /* stat(2)Information*/
} FTSENT;
La taille du fichier est en fts_stap
(stat).
python
struct stat {
dev_t st_dev; /*ID de l'appareil sur lequel se trouve le fichier*/
ino_t st_ino; /*numéro d'inode*/
mode_t st_mode; /*Protection d'accès*/
nlink_t st_nlink; /*Nombre de liens physiques*/
uid_t st_uid; /*ID utilisateur du propriétaire*/
gid_t st_gid; /*ID de groupe du propriétaire*/
dev_t st_rdev; /*Reference de l'appareil(Pour les fichiers spéciaux) */
off_t st_size; /*Taille globale(Unité d'octet) */
blksize_t st_blksize; /*Système de fichiers I/En O
Taille de bloc*/
blkcnt_t st_blocks; /*Nombre de blocs 512B alloués*/
};
Par conséquent, la taille du fichier peut être obtenue en traçant la structure statistique à partir de la structure FTSENT.
Maintenant, la structure FTSENT a été obtenue par fts_read ()
dans (2). Puisque fts_read ()
suit automatiquement la hiérarchie des fichiers, il semble que la commande du puisse être implémentée en appelant à plusieurs reprisesfts_read ()
et en totalisant la taille du fichier. Et le processus de totalisation de la taille du fichier se fait par process_file ()
dans (3).
Maintenant, avant d'entrer dans l'explication de (3), voyons l'opération de traçage de la hiérarchie des fichiers par fts_read ()
. Vérifiez l'opération avec le code suivant (Lire les ls de FreeBSD Faisons des ls avec fts (3) ~).
python
#include <stdio.h>
#include <stdlib.h>
#include <fts.h>
int main (int argc, char *argv[])
{
FTS *ftsp;
FTSENT *p;
static char dot[] = ".";
static char *dotav[] = {dot, NULL};
if (argc == 1)
argv = dotav;
else
argv++;
ftsp = fts_open(argv, 0, NULL);
while((p = fts_read(ftsp)) != NULL) {
printf("%s\n", p->fts_path);
}
fts_close(ftsp);
exit(EXIT_SUCCESS);
}
Ce code est une implémentation de la commande ls utilisant la fonction fts. Tous les fichiers et répertoires du répertoire sont affichés. Le fts_read ()
dans l'instruction while
suit la hiérarchie des fichiers, et le p-> fts_path
affiche le nom du fichier.
Le résultat de l'exécution est le suivant.
$ ./ls
.
./dir1
./dir1/file3
./dir1/file4
./dir1/dir2
./dir1/dir2/file5
./dir1/dir2
./dir1
./ls.c
./ls
./file2
./file1
.
L'ordre d'affichage est le suivant.
Vous pouvez voir que la profondeur est priorisée, le fichier est parcouru une fois et le répertoire est parcouru deux fois.
La prochaine fois verra le processus de process_file () dans (3).
Recommended Posts