Fonction récursive => segmention fault

Signaler
Messages postés
14
Date d'inscription
mercredi 24 novembre 2004
Statut
Membre
Dernière intervention
23 juin 2006
-
Messages postés
14
Date d'inscription
mercredi 24 novembre 2004
Statut
Membre
Dernière intervention
23 juin 2006
-
Bonjour, j'ai absolument besoin de votre aide !!



Lorque j'utilise ma fonction avec pour option -R pour afficher le
contenu du dossier, et si celui-ci en contient d’autre, cette option
affiche aussi leurs contenu (d'où la récursivité).



1er problème : elle affiche les fichiers ou dossiers en DOUBLE.

2ème prblème : elle retourne "segmention fault". La fontion ne fait pas la récursivité.



Pourquoi ?



Voici le code :



#include <stdio.h>

#include <stdlib.h>

#include <dirent.h>

#include <sys/stat.h>

#include <sys/types.h>

#include

#include <grp.h>

#include <time.h>

#include <string.h>

#include



typedef struct options_s{

int recursive, longdisplay, numeric, all, displaydirnames ;

} options_t ;

options_t _options = { 0, 0, 0, 0, 0 } ;



/* renvoie la dernière composante d'un chemin

(ce qui suit le dernier slash, s'il y en a un) */

char * afterslash (const char * name) {

char * path = strrchr (name, '/') ;



if (path == name) return path ;

if (!path) return strchr(name, name[0]) ;

else return path + 1 ;

}



/* une fonction qui indique si le nom commence par un point */

int allbutdotfiles (const struct dirent* d) {

char* realname = afterslash(d->d_name) ;

return realname[0]!='.' ;

}



/* une fonction qui indique si le nom est . ou .. */

int allbutdotand2dots (const struct dirent* d) {

char* realname = afterslash(d->d_name) ;



if (realname[0]!='.') return 1 ;

if (realname[1]=='\0') return 0 ;

if (realname[1]!='.') return 1 ;

if (realname[2]=='\0') return 0 ;

return 1 ;

}



/* affichage d'un fichier */

void printfile (char * name, options_t * options) {

struct stat s;

char access_chars [] = "rwxrwxrwx";

int access_masks [] = { 0400, 0200, 0100, 040, 020, 010, 4, 2, 1 };

char type_chars [] = "-dbcl";

int type_masks [] = { S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK };

struct passwd * p;

struct group * g;

int i ;

char date[12] ;



/* (avec option "-l") */

if ( ! options->longdisplay )

puts(afterslash(name));

else {

if ( lstat(name,&s) == -1) {

perror("lstat");

exit(-1);

}



for (i=0; i<strlen(type_chars); i++)

if (s.st_mode & type_masks[i]) {

putchar(type_chars[i]);

break;

}



if (i==strlen(type_chars)) putchar('?');



for (i=0; i<strlen(access_chars); i++) {

if (s.st_mode & access_masks[i]) putchar(access_chars[i]) ;

else putchar('-') ;

}



printf (" %4d ", s.st_nlink) ;



if (options->numeric)

printf("%-8d %-8d ",s.st_uid,s.st_gid) ;

else {

p = getpwuid (s.st_uid) ;

g = getgrgid (s.st_gid) ;



if (p) printf ("%-8s ",p->pw_name);

else printf ("%-8d ",s.st_uid);



if (g) printf ("%-8s ",g->gr_name);

else printf ("%-8d ",s.st_gid);

}

printf ("%8d ", s.st_size) ;



strftime (date,13,"%b %d %H:%M",gmtime(&s.st_mtime)) ;

printf ("%12s ",date) ;

}

name = afterslash (name) ;

puts(name) ;

}



/* affichage d'un fichier ou répertoire.

pour un fichier, on l'affiche simplement.

pour un répertoire, on fait une descente récursive

(si l'option -R est spécifiée) */

void printdirectory (char* name, options_t* options){

struct stat s;

struct dirent ** files;

int n, i;

char * fullname;



/* d'abord, si "name" ne correspond pas à un répertoire,

on l'affiche directement */

if ( stat(name,&s) == -1 ) {

perror("stat");

exit(-1);

}



if (!S_ISDIR(s.st_mode))

printfile (name,options) ;

/* sinon, c'est un répertoire, donc on va le parcourir */

else {

/* est-ce qu'on affiche tout (sauf . et ..), ou bien

est-ce qu'on cache les fichiers commençant par un point ? */

int(*selectfun)(const struct dirent*) =

options->all ? allbutdotand2dots : allbutdotfiles ;



n = scandir (name, &files, selectfun, alphasort) ;



if (n == -1) {

perror("scandir");

exit(-1);

}



if (options->displaydirnames || options->recursive)

printf("%s:\n",afterslash(name));



for (i=0; i<n; i++) {

fullname = (char *)malloc(strlen(name)+1+strlen(files[i]->d_name)+1);

if ( fullname == NULL ) {

perror("malloc");

exit(-1);

}



sprintf (fullname, "%s/%s", name, files[i]->d_name) ;

printfile (fullname,options) ;

free(fullname);

}

free(files);



/* maintenant, on fait l'éventuelle descente récursive */

if (options->recursive) {

for (i=0; i<n; i++) {

fullname = (char *)malloc(strlen(name)+1+strlen(files[i]->d_name)+1);

if ( fullname == NULL ) {

perror("malloc");

exit(-1);

}



sprintf (fullname, "%s/%s", name, files[i]->d_name) ;

if ( stat(fullname,&s) == -1 ) {

perror("stat");

exit(-1);

}



if (S_ISDIR(s.st_mode)) {

puts(""); /* pour séparer l'affichage des répertoires */

printdirectory (fullname, options) ;

}

free(fullname);

}

free(files);

}

}

}





int main (int c, char**v) {

options_t options = _options ;

int option ;

int i;



while (-1!=(option=getopt(c,v,"Rlna")))

switch (option) {

case 'R': options.recursive = 1; break;

case 'l': options.longdisplay = 1; break;

case 'n': options.numeric = 1; break;

case 'a': options.all = 1; break;

}



if (c == optind)

printdirectory(".",&options);

else {

if (optind < c-1)

options.displaydirnames++ ;



for (i=optind; i<c; i++) {

printdirectory(v[i],&options) ;



if (i+1!=c)

puts(""); /* pour séparer les différents répertoires */

}

}

return 0;

}

1 réponse

Messages postés
14
Date d'inscription
mercredi 24 novembre 2004
Statut
Membre
Dernière intervention
23 juin 2006

Pardon c'est 'Segmentation fault'