I've been having problems trying to implement something like ls -R on C, The thing is that I need list recursively list everything starting from a given directory and then do stuff with those regular files I get from the list. This is what I have so far:
void ls(char* path){
DIR *directory;
struct dirent *filei;
struct stat stats;
directory = opendir(path);
if (directory != NULL)
{
while ((filei=readdir(directory))!=NULL){
stat(filei->d_name, &stats);
printf(" %s\n", filei->d_name);
if (S_ISDIR(stats.st_mode)){
char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
strcpy(buf,path);
strcat(buf,"/");
strcat(buf,filei->d_name);
ls(buf);
}
}
closedir(directory);
}
else{
printf("Error.\n");
}
}
It doesn't work at all, it shows files that are not even in the folder I'm working with. Any thoughts? Thanks.
The following rework of your code calls stat()
on the full file path, skips over the "." and ".." directories, fixes the memory leak and adds just a touch of error handling:
#define SEPARATOR "/"
void ls(const char *path)
{
DIR *directory = opendir(path);
if (directory != NULL)
{
struct dirent *filei;
while ((filei = readdir(directory)) != NULL)
{
if (strcmp(filei->d_name, ".") == 0 || strcmp(filei->d_name, "..") == 0)
{
continue;
}
char *buffer = malloc(strlen(path) + strlen(filei->d_name) + strlen(SEPARATOR) + 1);
strcat(strcat(strcpy(buffer, path), SEPARATOR), filei->d_name);
struct stat stat_buffer;
if (stat(buffer, &stat_buffer) == 0)
{
printf("%s\n", buffer);
if (S_ISDIR(stat_buffer.st_mode))
{
ls(buffer);
}
}
else
{
perror(NULL);
}
free(buffer);
}
closedir(directory);
}
else
{
perror(NULL);
}
}
See if it works any better for you.