Directory Reading Issues in C

I am writing a simple C program that takes a directory as an argument and displays the files in that directory, as well as its subdirectories. I wrote a "recursive" function for this. But for some unknown reason, my program does not work with the function stat. Here is my program:

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s\n", path);
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent -> d_name, &stat_info) == -1){
     printf("readdir error for %s\n", dirent->d_name);
     exit(1);
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("File: %s \n", dirent -> d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;

if(argc > 1){
 path = argv[1];
} else {
 path = ".";
}

display_directory(path);

 return EXIT_SUCCESS;
}

For example, if in my directory A there are a1, a2, a3 and .., it first reads the directory .., and when it reads the directory a1, the function statfails.

Can someone tell me what is wrong with my code.

[EDIT] I have included <errno.h>, as many of you suggest, and after starting the program I have an error Too many open files.

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s --> %s\n", path, strerror(errno));
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent->d_name, &stat_info)){
     printf("readdir error for %s ---> %s\n", dirent->d_name, strerror(errno));
     continue;
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("Fichier : %s \n", dirent->d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;

if (argc > 2) { 
 fprintf(stderr, "Usage: %s [directory]\n", argv[0]); 
 exit(1); 
}

path = argv[1];


display_directory(path);

 return EXIT_SUCCESS;
}

Program Output:

[..]
[mykill.c]
readdir error for mykill.c ---> No such file or directory
[.]
Directory : .
[..]
[.]
Directory : .
[..]
[.]
Directory : .
[..]

...
...
Directory : .
opendir failure for . --> Too many open files

mykill.c is the file in the directory that was passed as an argument.

+2
4
if(S_ISDIR(stat_info.st_mode)){
 if( !strcmp(dirent->d_name, ".")) continue;
 if( !strcmp(dirent->d_name, "..")) continue;

 printf("Directory : %s\n", dirent->d_name);
 display_directory(dirent->d_name);
}
+1

, , , . ...

if(stat(dirent -> d_name, &stat_info) == -1){
  printf("readdir error for %s\n", dirent->d_name);
  exit(1);
}

... ...

if (stat(dirent->d_name, &stat_info)) {
    printf("%s: %s\n", dirent->d_name, strerror(errno));
    continue;
}

include

#include <errno.h>

. , , COMPLETE, UNEDITED , .

+5

You create stat only with the file name (without the full path), add the full path to the file name, or change the working directory before calling stat.

+1
source

Use nftw().

0
source

All Articles