IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Commande "du" en C, probleme à l'utilisation


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut Commande "du" en C, probleme à l'utilisation
    Bonsoir à tous!

    Comme régulièrement ces derniers temps je viens quérir vos lumières pour un projet en C qui me pose quelques soucis...
    Il s'agit d'implémenter en C une sorte de fonction "du" qui renvoie la taille d'un fichier ou dossier donné passé en parametre. Elle accepte 2 options :
    -L : Pour le parcours des liens symboliques.
    -b : Pour avoir la taille en octets plutot qu'en blocks.

    J'ai donc fièrement pondu ceci (et sans erreur à la compilation, s'il vous plait!) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <errno.h>
    #include <limits.h>
    #include <string.h>
     
    static int opt_follow_links=0;
    static int opt_apparent_size =0;
     
    /*valid_name retourne true si repertoire different de . ou ..*/
    int valid_name(const char *name)
    {
    	return strcmp(name,".") && strcmp(name,"..");
    }
     
     
     
    int du_file(const char* name)
    {
    	static int profondeur =0;  /*variable static, pour verifier le nombre de lien symbolique traverses*/
    	struct stat obj;
    	DIR* dir;
    	struct dirent *dire;
    	int status, size, fin;
    	char *pathname = "";
    	char linkname[PATH_MAX+1];
     
     
    	if(profondeur > 128)		/*Si plus de 128 liens symboliques, quitte. Valeur arbitraire*/
    	{
    		errno = ELOOP;
    		perror("Trop de liens symboliques :");
    		exit(EXIT_FAILURE);
    	}
     
    	status = lstat(name , &obj);  /*Stocke les donnees du fichier pointee dans obj*/
     
    	/*Gestion d'erreurs du lstat*/
    	if(status) 
    	{
    		perror("Probleme de lstat");
    		exit(EXIT_FAILURE);
    	}
     
     
    		/*Cas d'un fichier simple*/
    	if(S_ISREG(obj.st_mode))
    	{
    		return opt_apparent_size ? obj.st_size : obj.st_blocks;
    	}
     
    		/*Cas d'un repertoire*/
    	if(S_ISDIR(obj.st_mode))
    	{
    		size= opt_apparent_size?obj.st_size : obj.st_blocks;
    		/*Ouverture repertoire + Gestion d'erreur opendir*/
    		if ((dir = opendir(name)) == NULL) {
    			perror("Probleme d'opendir");
    			exit(EXIT_FAILURE);
    		}
    		while ((dire = readdir(dir))) {
    			if (valid_name(dire->d_name)) {
    				snprintf(pathname, PATH_MAX, "%s/%s", name, dire->d_name);
    				size += du_file(pathname);
    			}
    		}
     
    		/* gestion des erreurs */
    		if (errno != 0) {
    			perror("Probleme d'appel système");
    			exit(EXIT_FAILURE);
    		}
     
    		closedir(dir);
    		return size;
     
    	}
     
    		/*Cas d'un lien symbolique*/
    	if(S_ISLNK(obj.st_mode))
    	{
    		size= opt_apparent_size?obj.st_size : obj.st_blocks;
     
    		if(opt_follow_links)
    		{
    			profondeur += 1;
    			fin = readlink(name, linkname, PATH_MAX);
    			linkname[fin] = '\0';	
    				/* gestion des erreurs */
    			if (fin == (-1))
    			{
    				perror("Probleme de readlink");
    				exit(EXIT_FAILURE);
    			}
    			size += du_file(linkname);
     
    		}
     
    		return size;
    	}	
     
    	return 0;
    }
     
     
     
     
    int main(int argc, char* argv[])
    {
    	int i;
     
    	for(i=1; i<(argc-1); i++){
    		if(!strcmp(argv[i],"-L")){
    			opt_follow_links=1;
    		}else if(!strcmp(argv[i],"-b")){
    			opt_apparent_size=1;
    		}else{
    			printf("option incorrecte : %s \n", argv[i]);
    			exit(EXIT_FAILURE);
    		}
    	}
    	printf("Taille du fichier/dossier : %d \n", du_file(argv[argc-1]));
    	return 0;
     
     
    }
    Premier problême : quelque soit le fichier sur lequel j'appelle ma commande mdu, il me donne le double de la taille en blocks que me donne la commande du...

    Second problême : si j'appelle ma commande avec en parametre, un dossier, j'ai comme erreur : "Segmentation fault"... Et alors ça, c'est du tout nouveau pour moi. Jamais vu.

    J'espère que vous trouverez la patience et le temps de m'aider,
    Merci en tout cas.

    Des bisous.

  2. #2
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Pour ton premier problème, j'ai trouvé ça dans le man de du. Ca ressemble étrangement à ton erreur, mais je n'ai pas poussé très loin.

    Citation Envoyé par man du
    Sur les systèmes BSD, du affiche des tailles correspondant à la moitié de la taille réelle pour les fichiers situés sur un système HP-UX monté par NFS. Sur les systèmes HP-UX, les tailles sont doublées pour les fichiers montés par NFS depuis un système BSD. Ceci est dû à un défaut d'HP-UX, qui affecte également la version HP-UX de la commande du.
    Pour ton deuxième problème, je pense que cela vient de ton appel de snprintf. La chaîne passée en deuxième paramètre n'est pas déclarée en tant que constante, je présume donc que la fonction peut modifier ta chaîne. Or, la chaîne que tu passes pointes vers une chaîne de caractère statique, qui peut être située en mémoire à lecture seule.
    Avec ce type de variable, on déclare généralement le pointeur comme étant constant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char const *pathname = "";
    Or, avec cette déclaration, on obtient des warnings. Dans ton cas, je pense qu'il vaut mieux créer une chaîne de caractère de taille fixe, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char pathname[PATH_MAX];
    tu prendras moins de risques.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut
    Woaw! It works!

    J'étais justement en train de poster le résultat du debugger qui donnait justement l'erreur au niveau du snprintf() mais j'avais pas encore bien trouvé l'origine...

    Merci beaucoup Kirilenko! Ca fait 2 fois que tu m'aides, je vais devoir t'envoyer des fleurs

  4. #4
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    je vais devoir t'envoyer des fleurs
    Ne te sens pas obligé.

    Si ton sujet est résolu, tu peux cliquer sur le tag à cet effet.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo